0

I would like to align memory depending on the data size: 2-bytes boundary for int16t, 4-bytes boundary for int32t, etc. so no adresse-misaligned exception is raised. How can I achieve that on a risc-v platform? Thank you.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Wheatley
  • 162
  • 1
  • 7
  • The assembler data directives, .half and .word achieve those alignments. Further, there is the .align directive. Have you tried any of these? – Erik Eidt Aug 24 '22 at 23:59
  • @ErikEidt: Is that true in GAS for RISC-V, even if you put them after a string? I know that's true for classic MIPS assemblers (and MARS which is designed that way), so I'd guess maybe true for RARS but I doubt it for GAS / Clang. I'd expect you'd need `.p2align 2` to align by 2^2 = 4 bytes if you were sure the current position was 4-byte aligned before a `.word`. – Peter Cordes Aug 25 '22 at 00:08
  • @PeterCordes, good point; I can't speak to GAS for RISC V. I was attempting to ask the querent what they'd tried. As you point out, would be nice to know the toolchain as well. – Erik Eidt Aug 25 '22 at 00:12
  • @ErikEidt: I'd never recommend `.align`, you don't know if it's going to align to 2^N or N depending on the target OS and architecture (yes even within GAS). Always use `.p2align` or `.balign`. But yeah, alignment directives seem like a pretty obvious way to do this, e.g. the way a compiler does (https://godbolt.org/ and uncheck the "directives" filter) – Peter Cordes Aug 25 '22 at 00:32
  • @ErikEidt No, I've not try this. I would like to use only C-code in my program. Is assembly the only way to achieve this ? – Wheatley Aug 25 '22 at 08:23
  • The ABI that GCC/clang target has `alignof(int32_t) == 4`, so they already do this for you. (Look for the `.p2align` in the asm they generate when compiling a global variable: https://godbolt.org/z/hTzhddz4o). You posted an [assembly] question so of course you got an [assembly] answer. If you actually have C programs that generate alignment faults, that's a bug in your C program, and a totally different question of which this is not a [mcve]. – Peter Cordes Aug 25 '22 at 12:15
  • Accessing `int32_t` variables that you declared in C won't cause such faults. Casting unaligned pointers might (perhaps in a network buffer), but then you're not accessing variables you declared in C. And if you do need to access unaligned data, you need to do that; you could *copy* it to an aligned location, or change something earlier about how a buffer is allocated or something, but you can't just magically make a misaligned `int32_t*` work as aligned. – Peter Cordes Aug 25 '22 at 12:19
  • `memcpy` is usually a good way to express an unaligned load in C, but may not inline on RISC-V if it doesn't know the pointer is aligned. Or `__attribute__((aligned(1)))` may be useful to get a compiler to generate unaligned load/store instructions. Tried it: https://godbolt.org/z/Yn4bqh5fq - GCC inlines memcpy but as separate byte loads/stores, then an aligned reload. And doesn't seem to respect an `aligned(1)` attribute. Clang just use `lw` both times, apparently assuming that unaligned `lw` is safe? – Peter Cordes Aug 25 '22 at 12:21
  • https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf says that the "base" ISA supports unaligned loads/stores, but a subset of that could omit that support. So clang is assuming a RISC-V with (efficient) unaligned loads. Of course, it's still C undefined behaviour to dereference an `int *` that isn't aligned, and cause problems even when targeting an ISA where that's allowed in asm. ([Why does unaligned access to mmap'ed memory sometimes segfault on AMD64?](https://stackoverflow.com/q/47510783)) – Peter Cordes Aug 25 '22 at 12:34

0 Answers0