mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-21 18:29:45 +00:00
The long encoding for Thumb2 unconditional branches is broken. Additionally, there is no range checking for target operands; as such for instructions originating in assembly code, only short Thumb encodings are generated, regardless of the bitsize needed for the offset. Adding range checking is non trivial due to the representation of Thumb branch instructions. There is no true difference between conditional and unconditional branches in terms of operands and syntax - even unconditional branches have a predicate which is expected to match that of the IT block they are in. Yet, the encodings and the permitted size of the offset differ. Due to this, for any mnemonic there are really 4 encodings to choose for. The problem cannot be handled in the parser alone or by manipulating td files. Because the parser builds first a set of match candidates and then checks them one by one, whatever tablegen-only solution might be found will ultimately be dependent of the parser's evaluation order. What's worse is that due to the fact that all branches have the same syntax and the same kinds of operands, that order is governed by the lexicographical ordering of the names of operand classes... To circumvent all this, any necessary disambiguation is added to the instruction validation pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188067 91177308-0d34-0410-b5e6-96231b3b80d8
183 lines
6.0 KiB
ArmAsm
183 lines
6.0 KiB
ArmAsm
@ RUN: not llvm-mc -triple=thumbv6-apple-darwin < %s 2> %t
|
|
@ RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
|
|
@ RUN: not llvm-mc -triple=thumbv5-apple-darwin < %s 2> %t
|
|
@ RUN: FileCheck --check-prefix=CHECK-ERRORS-V5 < %t %s
|
|
|
|
@ Check for various assembly diagnostic messages on invalid input.
|
|
|
|
@ ADD instruction w/o 'S' suffix.
|
|
add r1, r2, r3
|
|
@ CHECK-ERRORS: error: invalid instruction
|
|
@ CHECK-ERRORS: add r1, r2, r3
|
|
@ CHECK-ERRORS: ^
|
|
|
|
@ Instructions which require v6+ for both registers to be low regs.
|
|
add r2, r3
|
|
mov r2, r3
|
|
@ CHECK-ERRORS: error: instruction variant requires Thumb2
|
|
@ CHECK-ERRORS: add r2, r3
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS-V5: error: instruction variant requires ARMv6 or later
|
|
@ CHECK-ERRORS-V5: mov r2, r3
|
|
@ CHECK-ERRORS-V5: ^
|
|
|
|
|
|
@ Out of range immediates for ASR instruction.
|
|
asrs r2, r3, #33
|
|
@ CHECK-ERRORS: error: invalid operand for instruction
|
|
@ CHECK-ERRORS: asrs r2, r3, #33
|
|
@ CHECK-ERRORS: ^
|
|
|
|
@ Out of range immediates for BKPT instruction.
|
|
bkpt #256
|
|
bkpt #-1
|
|
error: invalid operand for instruction
|
|
bkpt #256
|
|
^
|
|
error: invalid operand for instruction
|
|
bkpt #-1
|
|
^
|
|
|
|
@ Invalid writeback and register lists for LDM
|
|
ldm r2!, {r5, r8}
|
|
ldm r2, {r5, r7}
|
|
ldm r2!, {r2, r3, r4}
|
|
@ CHECK-ERRORS: error: registers must be in range r0-r7
|
|
@ CHECK-ERRORS: ldm r2!, {r5, r8}
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: writeback operator '!' expected
|
|
@ CHECK-ERRORS: ldm r2, {r5, r7}
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: writeback operator '!' not allowed when base register in register list
|
|
@ CHECK-ERRORS: ldm r2!, {r2, r3, r4}
|
|
@ CHECK-ERRORS: ^
|
|
|
|
|
|
@ Invalid writeback and register lists for PUSH/POP
|
|
pop {r1, r2, r10}
|
|
push {r8, r9}
|
|
@ CHECK-ERRORS: error: registers must be in range r0-r7 or pc
|
|
@ CHECK-ERRORS: pop {r1, r2, r10}
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: registers must be in range r0-r7 or lr
|
|
@ CHECK-ERRORS: push {r8, r9}
|
|
@ CHECK-ERRORS: ^
|
|
|
|
|
|
@ Invalid writeback and register lists for STM
|
|
stm r1, {r2, r6}
|
|
stm r1!, {r2, r9}
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: stm r1, {r2, r6}
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: registers must be in range r0-r7
|
|
@ CHECK-ERRORS: stm r1!, {r2, r9}
|
|
@ CHECK-ERRORS: ^
|
|
|
|
@ Out of range immediates for LSL instruction.
|
|
lsls r4, r5, #-1
|
|
lsls r4, r5, #32
|
|
@ CHECK-ERRORS: error: invalid operand for instruction
|
|
@ CHECK-ERRORS: lsls r4, r5, #-1
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: invalid operand for instruction
|
|
@ CHECK-ERRORS: lsls r4, r5, #32
|
|
@ CHECK-ERRORS: ^
|
|
|
|
@ Mismatched source/destination operands for MUL instruction.
|
|
muls r1, r2, r3
|
|
@ CHECK-ERRORS: error: destination register must match source register
|
|
@ CHECK-ERRORS: muls r1, r2, r3
|
|
@ CHECK-ERRORS: ^
|
|
|
|
|
|
@ Out of range immediates for STR instruction.
|
|
str r2, [r7, #-1]
|
|
str r5, [r1, #3]
|
|
str r3, [r7, #128]
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: str r2, [r7, #-1]
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: str r5, [r1, #3]
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: str r3, [r7, #128]
|
|
@ CHECK-ERRORS: ^
|
|
|
|
@ Out of range immediate for SVC instruction.
|
|
svc #-1
|
|
svc #256
|
|
@ CHECK-ERRORS: error: invalid operand for instruction
|
|
@ CHECK-ERRORS: svc #-1
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: arm-mode
|
|
@ CHECK-ERRORS: svc #256
|
|
@ CHECK-ERRORS: ^
|
|
|
|
|
|
@ Out of range immediate for ADD SP instructions
|
|
add sp, #-1
|
|
add sp, #3
|
|
add sp, sp, #512
|
|
add r2, sp, #1024
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: add sp, #-1
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: add sp, #3
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: add sp, sp, #512
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: arm-mode
|
|
@ CHECK-ERRORS: add r2, sp, #1024
|
|
@ CHECK-ERRORS: ^
|
|
|
|
add r2, sp, ip
|
|
@ CHECK-ERRORS: error: source register must be the same as destination
|
|
@ CHECK-ERRORS: add r2, sp, ip
|
|
@ CHECK-ERRORS: ^
|
|
|
|
|
|
@------------------------------------------------------------------------------
|
|
@ WFE/WFI/YIELD - out of range immediates for Thumb1 branches
|
|
@------------------------------------------------------------------------------
|
|
|
|
beq #-258
|
|
bne #256
|
|
bgt #13
|
|
b #-1048578
|
|
b #1048576
|
|
b #10323
|
|
|
|
@ CHECK-ERRORS: error: Branch target out of range
|
|
@ CHECK-ERRORS: error: Branch target out of range
|
|
@ CHECK-ERRORS: error: Branch target out of range
|
|
@ CHECK-ERRORS: error: Branch target out of range
|
|
@ CHECK-ERRORS: error: Branch target out of range
|
|
@ CHECK-ERRORS: error: Branch target out of range
|
|
|
|
@------------------------------------------------------------------------------
|
|
@ WFE/WFI/YIELD - are not supported pre v6T2
|
|
@------------------------------------------------------------------------------
|
|
wfe
|
|
wfi
|
|
yield
|
|
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: wfe
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: wfi
|
|
@ CHECK-ERRORS: ^
|
|
@ CHECK-ERRORS: error: instruction requires: thumb2
|
|
@ CHECK-ERRORS: yield
|
|
@ CHECK-ERRORS: ^
|
|
|
|
@------------------------------------------------------------------------------
|
|
@ PLDW required mp-extensions
|
|
@------------------------------------------------------------------------------
|
|
pldw [r0, #4]
|
|
@ CHECK-ERRORS: error: instruction requires: mp-extensions
|