diff options
author | Tim Northover <Tim.Northover@arm.com> | 2013-01-31 12:12:40 +0000 |
---|---|---|
committer | Tim Northover <Tim.Northover@arm.com> | 2013-01-31 12:12:40 +0000 |
commit | 72062f5744557e270a38192554c3126ea5f97434 (patch) | |
tree | ae6e4c8abb4e0572745e7849b4948c58fea3e8d0 /test/DebugInfo/AArch64 | |
parent | d72b4d321e317327330e1e82d0f652d4e237c171 (diff) | |
download | external_llvm-72062f5744557e270a38192554c3126ea5f97434.zip external_llvm-72062f5744557e270a38192554c3126ea5f97434.tar.gz external_llvm-72062f5744557e270a38192554c3126ea5f97434.tar.bz2 |
Add AArch64 as an experimental target.
This patch adds support for AArch64 (ARM's 64-bit architecture) to
LLVM in the "experimental" category. Currently, it won't be built
unless requested explicitly.
This initial commit should have support for:
+ Assembly of all scalar (i.e. non-NEON, non-Crypto) instructions
(except the late addition CRC instructions).
+ CodeGen features required for C++03 and C99.
+ Compilation for the "small" memory model: code+static data <
4GB.
+ Absolute and position-independent code.
+ GNU-style (i.e. "__thread") TLS.
+ Debugging information.
The principal omission, currently, is performance tuning.
This patch excludes the NEON support also reviewed due to an outbreak of
batshit insanity in our legal department. That will be committed soon bringing
the changes to precisely what has been approved.
Further reviews would be gratefully received.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174054 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/DebugInfo/AArch64')
-rw-r--r-- | test/DebugInfo/AArch64/cfi-frame.ll | 58 | ||||
-rw-r--r-- | test/DebugInfo/AArch64/eh_frame.ll | 51 | ||||
-rw-r--r-- | test/DebugInfo/AArch64/eh_frame_personality.ll | 46 | ||||
-rw-r--r-- | test/DebugInfo/AArch64/lit.local.cfg | 6 | ||||
-rw-r--r-- | test/DebugInfo/AArch64/variable-loc.ll | 87 |
5 files changed, 248 insertions, 0 deletions
diff --git a/test/DebugInfo/AArch64/cfi-frame.ll b/test/DebugInfo/AArch64/cfi-frame.ll new file mode 100644 index 0000000..4217925 --- /dev/null +++ b/test/DebugInfo/AArch64/cfi-frame.ll @@ -0,0 +1,58 @@ +; RUN: llc -verify-machineinstrs -march aarch64 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -march aarch64 -disable-fp-elim < %s | FileCheck %s --check-prefix=CHECK-WITH-FP + +@bigspace = global [8 x i64] zeroinitializer + +declare void @use_addr(i8*) + +define void @test_frame([8 x i64] %val) { +; CHECK: test_frame: +; CHECK: .cfi_startproc + + %var = alloca i8, i32 1000000 +; CHECK: sub sp, sp, #[[SP_INIT_ADJ:[0-9]+]] +; CHECK-NEXT: .Ltmp +; CHECK-NEXT: .cfi_def_cfa sp, [[SP_INIT_ADJ]] + +; Make sure the prologue is reasonably efficient +; CHECK-NEXT: stp x29, x30, [sp, +; CHECK-NEXT: stp x25, x26, [sp, +; CHECK-NEXT: stp x23, x24, [sp, +; CHECK-NEXT: stp x21, x22, [sp, +; CHECK-NEXT: stp x19, x20, [sp, +; CHECK-NEXT: sub sp, sp, #160 +; CHECK-NEXT: sub sp, sp, #244, lsl #12 +; CHECK-NEXT: .Ltmp +; CHECK-NEXT: .cfi_def_cfa sp, 1000080 +; CHECK-NEXT: .Ltmp +; CHECK-NEXT: .cfi_offset x30, -8 +; CHECK-NEXT: .Ltmp +; CHECK-NEXT: .cfi_offset x29, -16 +; [...] +; CHECK: .cfi_offset x19, -80 + +; CHECK: bl use_addr + call void @use_addr(i8* %var) + + store [8 x i64] %val, [8 x i64]* @bigspace + ret void +; CHECK: ret +; CHECK: .cfi_endproc +} + +; CHECK-WITH-FP: test_frame: + +; CHECK-WITH-FP: sub sp, sp, #[[SP_INIT_ADJ:[0-9]+]] +; CHECK-WITH-FP-NEXT: .Ltmp +; CHECK-WITH-FP-NEXT: .cfi_def_cfa sp, [[SP_INIT_ADJ]] + +; CHECK-WITH-FP: stp x29, x30, [sp, [[OFFSET:#[0-9]+]]] +; CHECK-WITH-FP-NEXT: add x29, sp, [[OFFSET]] +; CHECK-WITH-FP-NEXT: .Ltmp +; CHECK-WITH-FP-NEXT: .cfi_def_cfa x29, 16 + + ; We shouldn't emit any kind of update for the second stack adjustment if the + ; FP is in use. +; CHECK-WITH-FP-NOT: .cfi_def_cfa_offset + +; CHECK-WITH-FP: bl use_addr diff --git a/test/DebugInfo/AArch64/eh_frame.ll b/test/DebugInfo/AArch64/eh_frame.ll new file mode 100644 index 0000000..1343659 --- /dev/null +++ b/test/DebugInfo/AArch64/eh_frame.ll @@ -0,0 +1,51 @@ +; RUN: llc -verify-machineinstrs -march=aarch64 %s -filetype=obj -o %t +; RUN: llvm-objdump -s %t | FileCheck %s +@var = global i32 0 + +declare void @bar() + +define i64 @check_largest_class(i32 %in) { + %res = load i32* @var + call void @bar() + %ext = zext i32 %res to i64 + ret i64 %ext +} + +; The really key points we're checking here are: +; * Return register is x30. +; * Pointer format is 0x1b (GNU doesn't appear to understand others). + +; The rest is largely incidental, but not expected to change regularly. + +; Output is: + +; CHECK: Contents of section .eh_frame: +; CHECK-NEXT: 0000 10000000 00000000 017a5200 017c1e01 .........zR..|.. +; CHECK-NEXT: 0010 1b0c1f00 18000000 18000000 00000000 ................ + + +; Won't check the rest, it's rather incidental. +; 0020 24000000 00440c1f 10449e02 93040000 $....D...D...... + + +; The first CIE: +; ------------------- +; 10000000: length of first CIE = 0x10 +; 00000000: This is a CIE +; 01: version = 0x1 +; 7a 52 00: augmentation string "zR" -- pointer format is specified +; 01: code alignment factor 1 +; 7c: data alignment factor -4 +; 1e: return address register 30 (== x30). +; 01: 1 byte of augmentation +; 1b: pointer format 1b: DW_EH_PE_pcrel | DW_EH_PE_sdata4 +; 0c 1f 00: initial instructions: "DW_CFA_def_cfa x31 ofs 0" in this case + +; Next the FDE: +; ------------- +; 18000000: FDE length 0x18 +; 18000000: Uses CIE 0x18 backwards (only coincidentally same as above) +; 00000000: PC begin for this FDE is at 00000000 (relocation is applied here) +; 24000000: FDE applies up to PC begin+0x24 +; 00: Augmentation string length 0 for this FDE +; Rest: call frame instructions diff --git a/test/DebugInfo/AArch64/eh_frame_personality.ll b/test/DebugInfo/AArch64/eh_frame_personality.ll new file mode 100644 index 0000000..ab06d21 --- /dev/null +++ b/test/DebugInfo/AArch64/eh_frame_personality.ll @@ -0,0 +1,46 @@ +; RUN: llc -verify-machineinstrs -march=aarch64 %s -filetype=obj -o %t +; RUN: llvm-objdump -s %t | FileCheck %s + +declare i32 @__gxx_personality_v0(...) + +declare void @bar() + +define i64 @foo(i64 %lhs, i64 %rhs) { + invoke void @bar() to label %end unwind label %clean +end: + ret i64 0 + +clean: + %tst = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) cleanup + ret i64 42 +} + +; CHECK: Contents of section .eh_frame: +; CHECK: 0000 1c000000 00000000 017a504c 5200017c .........zPLR..| +; CHECK: 0010 1e0b0000 00000000 00000000 1b0c1f00 ................ + +; Don't really care about the rest: + +; 0020 1c000000 24000000 00000000 24000000 ....$.......$... +; 0030 08000000 00000000 00440c1f 10449e02 .........D...D.. + +; The key test here is that the personality routine is sanely encoded (under the +; small memory model it must be an 8-byte value for full generality: code+data < +; 4GB, but you might need both +4GB and -4GB depending on where things end +; up. However, for completeness: + +; First CIE: +; ---------- +; 1c000000: Length = 0x1c +; 00000000: This is a CIE +; 01: Version 1 +; 7a 50 4c 52 00: Augmentation string "zPLR" (personality routine, language-specific data, pointer format) +; 01: Code alignment factor 1 +; 78: Data alignment factor: -8 +; 1e: Return address in x30 +; 07: Augmentation data 0xb bytes (this is key!) +; 00: Personality encoding is DW_EH_PE_absptr +; 00 00 00 00 00 00 00 00: First part of aug (personality routine). Relocated, obviously +; 00: Second part of aug (language-specific data): absolute pointer format used +; 1b: pointer format: pc-relative signed 4-byte. Just like GNU. +; 0c 1f 00: Initial instructions ("DW_CFA_def_cfa x31 ofs 0" in this case) diff --git a/test/DebugInfo/AArch64/lit.local.cfg b/test/DebugInfo/AArch64/lit.local.cfg new file mode 100644 index 0000000..c5ce241 --- /dev/null +++ b/test/DebugInfo/AArch64/lit.local.cfg @@ -0,0 +1,6 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'AArch64' in targets: + config.unsupported = True + diff --git a/test/DebugInfo/AArch64/variable-loc.ll b/test/DebugInfo/AArch64/variable-loc.ll new file mode 100644 index 0000000..3277204 --- /dev/null +++ b/test/DebugInfo/AArch64/variable-loc.ll @@ -0,0 +1,87 @@ +; RUN: llc -march=aarch64 -disable-fp-elim < %s | FileCheck %s + +; This is a regression test making sure the location of variables is correct in +; debugging information, even if they're addressed via the frame pointer. + + ; First make sure main_arr is where we expect it: sp + 12 == x29 - 420: +; CHECK: main: +; CHECK: sub sp, sp, #448 +; CHECK: stp x29, x30, [sp, #432] +; CHECK: add x29, sp, #432 +; CHECK: add {{x[0-9]+}}, sp, #12 + + ; Now check the debugging information reflects this: +; CHECK: DW_TAG_variable +; CHECK-NEXT: .word .Linfo_string7 + + ; Rather hard-coded, but 145 => DW_OP_fbreg and the .ascii is LEB128 encoded -420. +; CHECK: DW_AT_location +; CHECK-NEXT: .byte 145 +; CHECK-NEXT: .ascii "\334|" + +; CHECK: .Linfo_string7: +; CHECK-NEXT: main_arr + + +target datalayout = "e-p:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-f128:128:128-n32:64-S128" +target triple = "aarch64-none-linux-gnu" + +@.str = private unnamed_addr constant [13 x i8] c"Total is %d\0A\00", align 1 + +declare void @populate_array(i32*, i32) nounwind + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare i32 @sum_array(i32*, i32) nounwind + +define i32 @main() nounwind { +entry: + %retval = alloca i32, align 4 + %main_arr = alloca [100 x i32], align 4 + %val = alloca i32, align 4 + store i32 0, i32* %retval + call void @llvm.dbg.declare(metadata !{[100 x i32]* %main_arr}, metadata !17), !dbg !22 + call void @llvm.dbg.declare(metadata !{i32* %val}, metadata !23), !dbg !24 + %arraydecay = getelementptr inbounds [100 x i32]* %main_arr, i32 0, i32 0, !dbg !25 + call void @populate_array(i32* %arraydecay, i32 100), !dbg !25 + %arraydecay1 = getelementptr inbounds [100 x i32]* %main_arr, i32 0, i32 0, !dbg !26 + %call = call i32 @sum_array(i32* %arraydecay1, i32 100), !dbg !26 + store i32 %call, i32* %val, align 4, !dbg !26 + %0 = load i32* %val, align 4, !dbg !27 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0), i32 %0), !dbg !27 + ret i32 0, !dbg !28 +} + +declare i32 @printf(i8*, ...) + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"simple.c", metadata !"/home/timnor01/a64-trunk/build", metadata !"clang version 3.2 ", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] [/home/timnor01/a64-trunk/build/simple.c] [DW_LANG_C99] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5, metadata !11, metadata !14} +!5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"populate_array", metadata !"populate_array", metadata !"", metadata !6, i32 4, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32*, i32)* @populate_array, null, null, metadata !1, i32 4} ; [ DW_TAG_subprogram ] [line 4] [def] [populate_array] +!6 = metadata !{i32 786473, metadata !"simple.c", metadata !"/home/timnor01/a64-trunk/build", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!8 = metadata !{null, metadata !9, metadata !10} +!9 = metadata !{i32 786447, null, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int] +!10 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!11 = metadata !{i32 786478, i32 0, metadata !6, metadata !"sum_array", metadata !"sum_array", metadata !"", metadata !6, i32 9, metadata !12, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32*, i32)* @sum_array, null, null, metadata !1, i32 9} ; [ DW_TAG_subprogram ] [line 9] [def] [sum_array] +!12 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !13, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!13 = metadata !{metadata !10, metadata !9, metadata !10} +!14 = metadata !{i32 786478, i32 0, metadata !6, metadata !"main", metadata !"main", metadata !"", metadata !6, i32 18, metadata !15, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, metadata !1, i32 18} ; [ DW_TAG_subprogram ] [line 18] [def] [main] +!15 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !16, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!16 = metadata !{metadata !10} +!17 = metadata !{i32 786688, metadata !18, metadata !"main_arr", metadata !6, i32 19, metadata !19, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [main_arr] [line 19] +!18 = metadata !{i32 786443, metadata !14, i32 18, i32 16, metadata !6, i32 4} ; [ DW_TAG_lexical_block ] [/home/timnor01/a64-trunk/build/simple.c] +!19 = metadata !{i32 786433, null, metadata !"", null, i32 0, i64 3200, i64 32, i32 0, i32 0, metadata !10, metadata !20, i32 0, i32 0} ; [ DW_TAG_array_type ] [line 0, size 3200, align 32, offset 0] [from int] +!20 = metadata !{metadata !21} +!21 = metadata !{i32 786465, i64 0, i64 99} ; [ DW_TAG_subrange_type ] [0, 99] +!22 = metadata !{i32 19, i32 7, metadata !18, null} +!23 = metadata !{i32 786688, metadata !18, metadata !"val", metadata !6, i32 20, metadata !10, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [val] [line 20] +!24 = metadata !{i32 20, i32 7, metadata !18, null} +!25 = metadata !{i32 22, i32 3, metadata !18, null} +!26 = metadata !{i32 23, i32 9, metadata !18, null} +!27 = metadata !{i32 24, i32 3, metadata !18, null} +!28 = metadata !{i32 26, i32 3, metadata !18, null} |