move inline assembly constant out into C code so it doesn't get out of range in a large function (#602)

This commit is contained in:
Graham Sanderson 2021-10-12 09:07:06 -05:00 committed by GitHub
parent e76d5a9008
commit 30673fb6d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -159,19 +159,18 @@ static inline void *resolve_branch(uint16_t *inst) {
// GCC produces horrible code for subtraction of pointers here, and it was bugging me
static inline int8_t slot_diff(struct irq_handler_chain_slot *to, struct irq_handler_chain_slot *from) {
static_assert(sizeof(struct irq_handler_chain_slot) == 12, "");
int32_t result;
int32_t result = 0xaaaa;
// return (to - from);
// note this implementation has limited range, but is fine for plenty more than -128->127 result
asm (".syntax unified\n"
"subs %1, %2\n"
"adcs %1, %1\n" // * 2 (and + 1 if negative for rounding)
"ldr %0, =0xaaaa\n"
"muls %0, %1\n"
"lsrs %0, 20\n"
: "=l" (result), "+l" (to)
: "l" (from)
:
);
: "+l" (result), "+l" (to)
: "l" (from)
:
);
return (int8_t)result;
}