127 lines · plain
1// RUN: not llvm-mc -triple=thumbv7 -show-encoding < %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V7 %s2// RUN: not llvm-mc -triple=thumbv8 -show-encoding < %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V8 %s3 4 // Tests to check handling of sp and pc in thumb mov instructions. We5 // have to be careful about the order of things, as stdout/stderr6 // buffering means the errors appear before the non-error output, so7 // we have to put all the error checks at the top.8 9 // First check instructions that are never valid. These are thumb210 // instructions that uses pc11 12 // t2MOVr selected because no thumb1 movs that can access high regs13 movs pc, r014 movs r0, pc15 movs pc, pc16// CHECK: error: invalid instruction, any one of the following would fix this:17// CHECK-NEXT: movs pc, r018// CHECK: note: operand must be a register in range [r0, r14]19// CHECK: note: invalid operand for instruction20// CHECK: error: invalid instruction, any one of the following would fix this:21// CHECK-NEXT: movs r0, pc22// CHECK: note: operand must be a register in range [r0, r14]23// CHECK: note: invalid operand for instruction24// CHECK: error: invalid operand for instruction25// CHECK-NEXT: movs pc, pc26 27 // mov.w selects t2MOVr28 mov.w pc, r029 mov.w r0, pc30 mov.w pc, pc31// CHECK: error: operand must be a register in range [r0, r14]32// CHECK-NEXT: mov.w pc, r033// CHECK: note: operand must be a register in range [r0, r14]34// CHECK-NEXT: mov.w r0, pc35// CHECK: note: invalid operand for instruction36// CHECK-NEXT: mov.w r0, pc37// CHECK: error: invalid instruction38// CHECK-NEXT: mov.w pc, pc39 40 // movs.w selects t2MOVr41 movs.w pc, r042 movs.w r0, pc43 movs.w pc, pc44// CHECK: error: invalid instruction, any one of the following would fix this:45// CHECK-NEXT: movs.w pc, r046// CHECK: note: operand must be a register in range [r0, r14]47// CHECK: note: invalid operand for instruction48// CHECK: error: invalid instruction, any one of the following would fix this:49// CHECK-NEXT: movs.w r0, pc50// CHECK: note: operand must be a register in range [r0, r14]51// CHECK: note: invalid operand for instruction52// CHECK: error: invalid operand for instruction53// CHECK-NEXT: movs.w pc, pc54 55 56 // Now check instructions that are invalid before ARMv8 due to SP usage57 58 movs sp, r059 movs r0, sp60 movs sp, sp61// CHECK-V7: error: invalid instruction, any one of the following would fix this:62// CHECK-V7-NEXT: movs sp, r063// CHECK-V7: note: instruction variant requires ARMv8 or later64// CHECK-V7: note: operand must be a register in range [r0, r7]65// CHECK-V7: error: invalid instruction, any one of the following would fix this:66// CHECK-V7-NEXT: movs r0, sp67// CHECK-V7: note: instruction variant requires ARMv8 or later68// CHECK-V7: note: invalid operand for instruction69// CHECK-V7: note: operand must be an immediate in the range [0,255] or a relocatable expression70// CHECK-V7: note: operand must be a register in range [r0, r7]71// CHECK-V7: error: instruction variant requires ARMv8 or later72// CHECK-V7-NEXT: movs sp, sp73// CHECK-V8: movs.w sp, r0 @ encoding: [0x5f,0xea,0x00,0x0d]74// CHECK-V8: movs.w r0, sp @ encoding: [0x5f,0xea,0x0d,0x00]75// CHECK-V8: movs.w sp, sp @ encoding: [0x5f,0xea,0x0d,0x0d]76 77 mov.w sp, sp78// CHECK-V7: error: invalid instruction, any one of the following would fix this:79// CHECK-V7-NEXT: mov.w sp, sp80// CHECK-V7: note: instruction variant requires ARMv8 or later81// CHECK-V8: mov.w sp, sp @ encoding: [0x4f,0xea,0x0d,0x0d]82 83 movs.w sp, r084 movs.w r0, sp85 movs.w sp, sp86// CHECK-V7: error: instruction variant requires ARMv8 or later87// CHECK-V7-NEXT: movs.w sp, r088// CHECK-V7: error: invalid instruction, any one of the following would fix this:89// CHECK-V7-NEXT: movs.w r0, sp90// CHECK-V7: note: instruction variant requires ARMv8 or later91// CHECK-V7: error: instruction variant requires ARMv8 or later92// CHECK-V7-NEXT: movs.w sp, sp93// CHECK-V8: movs.w sp, r0 @ encoding: [0x5f,0xea,0x00,0x0d]94// CHECK-V8: movs.w r0, sp @ encoding: [0x5f,0xea,0x0d,0x00]95// CHECK-V8: movs.w sp, sp @ encoding: [0x5f,0xea,0x0d,0x0d]96 97 98 // Now instructions that are always valid99 100 // mov selects tMOVr, where sp and pc are allowed101 mov sp, r0102 mov r0, sp103 mov sp, sp104 mov pc, r0105 mov r0, pc106 mov pc, pc107// CHECK: mov sp, r0 @ encoding: [0x85,0x46]108// CHECK: mov r0, sp @ encoding: [0x68,0x46]109// CHECK: mov sp, sp @ encoding: [0xed,0x46]110// CHECK: mov pc, r0 @ encoding: [0x87,0x46]111// CHECK: mov r0, pc @ encoding: [0x78,0x46]112// CHECK: mov pc, pc @ encoding: [0xff,0x46]113 114 // sp allowed in non-flags-setting t2MOVr115 mov.w sp, r0116 mov.w r0, sp117// CHECK: mov.w sp, r0 @ encoding: [0x4f,0xea,0x00,0x0d]118// CHECK: mov.w r0, sp @ encoding: [0x4f,0xea,0x0d,0x00]119 120 // `movs pc, lr` is an alias for `subs pc, lr, #0`/`eret`.121 movs pc, lr122 movs.w pc, lr123// CHECK-V7: subs pc, lr, #0 @ encoding: [0xde,0xf3,0x00,0x8f]124// CHECK-V7: subs pc, lr, #0 @ encoding: [0xde,0xf3,0x00,0x8f]125// CHECK-V8: eret @ encoding: [0xde,0xf3,0x00,0x8f]126// CHECK-V8: eret @ encoding: [0xde,0xf3,0x00,0x8f]127