Browse Source

machine: fix a case of undefined behaviour with SP handling (#245)

The use of `asm` for register aliasing is supported in two different
contexts:
- local variables (including GNU expression statements) where it may
  only be used for specifying registers for input and output operands to
  extended `asm` syntax.

  c.f. https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables

- global variables where it may be used to observe the contents of a
  register.

  c.f. https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html#Global-Register-Variables

The two options here is to either to hoist the variable out into a
global variable, but then it should not be in a header due to fears of
ODR in case the optimizer does not inline it away, and thus becomes a
bit more tricky.  The alternative that this change actually adopts is to
explicitly use a move to copy the value out via the GNU extended
assembly syntax.

With this change, it is now possible to build the Proxy Kernel
completely with clang/LLVM and link with LLD.  The generated kernel also
runs under SPIKE and behaves as expected in a simple smoke test (without
any executable prints the expected message, and runs a trivial RVV
example).
remap
Saleem Abdulrasool 5 years ago
committed by GitHub
parent
commit
5450c2f731
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      machine/mtrap.h

11
machine/mtrap.h

@ -48,9 +48,14 @@ typedef struct {
volatile uint32_t* plic_s_ie;
} hls_t;
#define MACHINE_STACK_TOP() ({ \
register uintptr_t sp asm ("sp"); \
(void*)((sp + RISCV_PGSIZE) & -RISCV_PGSIZE); })
#define STACK_POINTER() ({ \
uintptr_t __sp; \
__asm__("mv %0, sp" : "=r"(__sp)); \
__sp; \
})
#define MACHINE_STACK_TOP() \
({ (void*)((STACK_POINTER() + RISCV_PGSIZE) & -RISCV_PGSIZE); })
// hart-local storage, at top of stack
#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))

Loading…
Cancel
Save