gcc's assembler and variable type (length, sign)

Viewed 130

I'm using an 'm68k-elf-as' compiler (https://gnutoolchains.com/m68k-elf/) for assembly code that I'm patching into my car's ECU (CPU32 ISA, MC68376 processor).

Is there a simple way to control typecasting in the gnu assembler? I'm having trouble with data sign and length.

Here are examples of my troubles

1) Sign: I use a quick move instruction that takes 8-bits of immediate data, sign-extends it, and places it into a data register:

MOVEQ #136,%D0

and the assembler complains 'Error: operands mismatch -- statement `moveq #136,%D0' ignored' This only compiles if I write the two's complement: 'MOVEQ #-120,%D0'

I recognize that the value in D0 contains sign, so inflexible interpretation of this instruction requires that I write in a signed 8-bit value, but the end-use of what is in the register in my code is dictated by subsequent instructions. i.e. my next instruction acts on 8-bits of data and I use the value as unsigned. bits are bits.

Is there a simple way to make the .as compiler take whatever 8-bit value I write, rather than excluding something based on assumption of a signed value?

2) Length: I use a jump table based on in-line data to jump to code relative to the current program counter:

MOVE.W 0x6(%PC,%D0.W),%D0 |code prior to this makes sure that D0 contains an even value <=18
JMP 0x2(%PC,%D0.W)   
jump_start:
.word end_routine-jump_start    | this does not compile correctly
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word continue_routine-jump_start  |if D0 contains 18, then we continue in the routine
BRA.W end_routine
continue_routine:

When this compiles, the 'jump_start' label is at address 0x31072, and the end_routine address is at 0x314e0, so the inline data should be: 0x046e, easily fitting in the 16-bit .word directive that I wrote. However, the compiler fails to correctly calculate this unless I use a .long directive.

Is there a simple way to get the compiler to calculate the value using the necessary 32-bits and then cast or mask it to 16 bits, while still retaining the in-line jump table data?

one more thing: I explicitly added a 'branch always' command at the end of the data in the jump table, but then the compiler adds more lines of similar nature:

BRA.W $456 |branch to end_routine, added by me
BRA.W $e   |branch to continue_routine, added by compiler
BRA.L $a   |branch to continue_routine, added by compiler
BRA.L $448 |branch to end_routine, added by the compiler
continue_routine:

Is there a simple way to make the compiler not add extra code? I already avoid compiling through .gcc before using .as because of the extra code it adds...

0 Answers
Related