1; Show that we know how to translate LDR/LDRH (register) instructions. 2 3; NOTE: We use -O2 to get rid of memory stores. 4 5; REQUIRES: allow_dump 6 7; Compile using standalone assembler. 8; RUN: %lc2i --filetype=asm -i %s --target=arm32 --args -O2 \ 9; RUN: | FileCheck %s --check-prefix=ASM 10 11; Show bytes in assembled standalone code. 12; RUN: %lc2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \ 13; RUN: --args -O2 | FileCheck %s --check-prefix=DIS 14 15; Compile using integrated assembler. 16; RUN: %lc2i --filetype=iasm -i %s --target=arm32 --args -O2 \ 17; RUN: | FileCheck %s --check-prefix=IASM 18 19; Show bytes in assembled integrated code. 20; RUN: %lc2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \ 21; RUN: --args -O2 | FileCheck %s --check-prefix=DIS 22 23; Define some global arrays to access. 24@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 25 26@Arrays = internal constant <{ i32, [4 x i8] }> <{ i32 ptrtoint ([40 x i8]* @ArrayInitPartial to i32), [4 x i8] c"\14\00\00\00" }>, align 4 27 28; Index elements of an array. 29define internal i32 @IndexArray(i32 %WhichArray, i32 %Len) { 30; ASM-LABEL:IndexArray: 31; DIS-LABEL:00000000 <IndexArray>: 32; IASM-LABEL:IndexArray: 33 34entry: 35; ASM-NEXT:.LIndexArray$entry: 36; IASM-NEXT:.LIndexArray$entry: 37 38 %gep_array = mul i32 %WhichArray, 8 39 40; ASM-NEXT: push {r4} 41; DIS-NEXT: 0: e52d4004 42; IASM-NEXT: .byte 0x4 43; IASM-NEXT: .byte 0x40 44; IASM-NEXT: .byte 0x2d 45; IASM-NEXT: .byte 0xe5 46 47; ASM-NEXT: lsl r2, r0, #3 48; DIS-NEXT: 4: e1a02180 49; IASM-NEXT: .byte 0x80 50; IASM-NEXT: .byte 0x21 51; IASM-NEXT: .byte 0xa0 52; IASM-NEXT: .byte 0xe1 53 54 %expanded1 = ptrtoint <{ i32, [4 x i8] }>* @Arrays to i32 55 %gep = add i32 %expanded1, %gep_array 56 57; ASM-NEXT: movw r3, #:lower16:Arrays 58; DIS-NEXT: 8: e3003000 59; IASM-NEXT: movw r3, #:lower16:Arrays @ .word e3003000 60 61; ASM-NEXT: movt r3, #:upper16:Arrays 62; DIS-NEXT: c: e3403000 63; IASM-NEXT: movt r3, #:upper16:Arrays @ .word e3403000 64 65 %gep3 = add i32 %gep, 4 66 67; ASM-NEXT: add r4, r3, #4 68; DIS-NEXT: 10: e2834004 69; IASM-NEXT: .byte 0x4 70; IASM-NEXT: .byte 0x40 71; IASM-NEXT: .byte 0x83 72; IASM-NEXT: .byte 0xe2 73 74; ***** Here is the use of a LDR (register) instruction. 75 %gep3.asptr = inttoptr i32 %gep3 to i32* 76 %v1 = load i32, i32* %gep3.asptr, align 1 77 78; ASM-NEXT: ldr r4, [r4, r0, lsl #3] 79; DIS-NEXT: 14: e7944180 80; IASM-NEXT: .byte 0x80 81; IASM-NEXT: .byte 0x41 82; IASM-NEXT: .byte 0x94 83; IASM-NEXT: .byte 0xe7 84 85 %Len.asptr3 = inttoptr i32 %Len to i32* 86 store i32 %v1, i32* %Len.asptr3, align 1 87 88; ASM-NEXT: str r4, [r1] 89; DIS-NEXT: 18: e5814000 90; IASM-NEXT: .byte 0x0 91; IASM-NEXT: .byte 0x40 92; IASM-NEXT: .byte 0x81 93; IASM-NEXT: .byte 0xe5 94 95 ; Now read the value as an i16 to test ldrh (register). 96 %gep3.i16ptr = inttoptr i32 %gep3 to i16* 97 %v16 = load i16, i16* %gep3.i16ptr, align 1 98 99; ASM-NEXT: add r3, r3, #4 100; DIS-NEXT: 1c: e2833004 101; IASM-NEXT: .byte 0x4 102; IASM-NEXT: .byte 0x30 103; IASM-NEXT: .byte 0x83 104; IASM-NEXT: .byte 0xe2 105 106; ***** Here is the use of a LDRH (register) instruction. 107; ASM-NEXT: ldrh r3, [r3, r2] 108; DIS-NEXT: 20: e19330b2 109; IASM-NEXT: .byte 0xb2 110; IASM-NEXT: .byte 0x30 111; IASM-NEXT: .byte 0x93 112; IASM-NEXT: .byte 0xe1 113 114 %ret = sext i16 %v16 to i32 115 ret i32 %ret 116} 117