diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-02-23 19:15:24 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-02-23 19:15:24 +0000 |
commit | a70f28ce7dc85d0075a7d86da5d7987b6e306bc6 (patch) | |
tree | fe6fdbcfb4cb0969874e482a41654e709108ef40 /test/CodeGen/MBlaze | |
parent | 2cce3712fafb2e72e144414377cd48f5ab95a5ae (diff) | |
download | llvm-a70f28ce7dc85d0075a7d86da5d7987b6e306bc6.tar.gz llvm-a70f28ce7dc85d0075a7d86da5d7987b6e306bc6.tar.bz2 llvm-a70f28ce7dc85d0075a7d86da5d7987b6e306bc6.tar.xz |
Adding the MicroBlaze backend.
The MicroBlaze is a highly configurable 32-bit soft-microprocessor for
use on Xilinx FPGAs. For more information see:
http://www.xilinx.com/tools/microblaze.htm
http://en.wikipedia.org/wiki/MicroBlaze
The current LLVM MicroBlaze backend generates assembly which can be
compiled using the an appropriate binutils assembler.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96969 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/MBlaze')
-rw-r--r-- | test/CodeGen/MBlaze/brind.ll | 73 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/callind.ll | 80 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/cc.ll | 315 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/dg.exp | 5 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/div.ll | 75 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/fpu.ll | 66 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/fsl.ll | 323 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/imm.ll | 70 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/jumptable.ll | 79 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/loop.ll | 47 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/mul.ll | 51 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/mul64.ll | 23 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/select.ll | 15 | ||||
-rw-r--r-- | test/CodeGen/MBlaze/shift.ll | 117 |
14 files changed, 1339 insertions, 0 deletions
diff --git a/test/CodeGen/MBlaze/brind.ll b/test/CodeGen/MBlaze/brind.ll new file mode 100644 index 0000000000..7798e0f56a --- /dev/null +++ b/test/CodeGen/MBlaze/brind.ll @@ -0,0 +1,73 @@ +; Ensure that the select instruction is supported and is lowered to +; some sort of branch instruction. +; +; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s + +declare i32 @printf(i8*, ...) +@MSG = internal constant [13 x i8] c"Message: %d\0A\00" + +@BLKS = private constant [5 x i8*] + [ i8* blockaddress(@brind, %L1), + i8* blockaddress(@brind, %L2), + i8* blockaddress(@brind, %L3), + i8* blockaddress(@brind, %L4), + i8* blockaddress(@brind, %L5) ] + +define i32 @brind(i32 %a, i32 %b) +{ + ; CHECK: brind: +entry: + br label %loop + +loop: + %tmp.0 = phi i32 [ 0, %entry ], [ %tmp.8, %finish ] + %dst.0 = getelementptr [5 x i8*]* @BLKS, i32 0, i32 %tmp.0 + %dst.1 = load i8** %dst.0 + indirectbr i8* %dst.1, [ label %L1, + label %L2, + label %L3, + label %L4, + label %L5 ] + ; CHECK: br {{r[0-9]*}} + +L1: + %tmp.1 = add i32 %a, %b + br label %finish + ; CHECK: br + +L2: + %tmp.2 = sub i32 %a, %b + br label %finish + ; CHECK: br + +L3: + %tmp.3 = mul i32 %a, %b + br label %finish + ; CHECK: br + +L4: + %tmp.4 = sdiv i32 %a, %b + br label %finish + ; CHECK: br + +L5: + %tmp.5 = srem i32 %a, %b + br label %finish + ; CHECK: br + +finish: + %tmp.6 = phi i32 [ %tmp.1, %L1 ], + [ %tmp.2, %L2 ], + [ %tmp.3, %L3 ], + [ %tmp.4, %L4 ], + [ %tmp.5, %L5 ] + + call i32 (i8*,...)* @printf( i8* getelementptr([13 x i8]* @MSG,i32 0,i32 0), + i32 %tmp.6) + + %tmp.7 = add i32 %tmp.0, 1 + %tmp.8 = urem i32 %tmp.7, 5 + + br label %loop + ; CHECK: br +} diff --git a/test/CodeGen/MBlaze/callind.ll b/test/CodeGen/MBlaze/callind.ll new file mode 100644 index 0000000000..bfc8d001fd --- /dev/null +++ b/test/CodeGen/MBlaze/callind.ll @@ -0,0 +1,80 @@ +; Ensure that indirect calls work and that they are lowered to some +; sort of branch and link instruction. +; +; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s + +declare i32 @printf(i8*, ...) +@MSG = internal constant [13 x i8] c"Message: %d\0A\00" + +@FUNS = private constant [5 x i32 (i32,i32)*] + [ i32 (i32,i32)* @doadd, + i32 (i32,i32)* @dosub, + i32 (i32,i32)* @domul, + i32 (i32,i32)* @dodiv, + i32 (i32,i32)* @dorem ] + +define i32 @doadd(i32 %a, i32 %b) +{ + ; CHECK: doadd: + %tmp.0 = add i32 %a, %b + ret i32 %tmp.0 + ; CHECK: rtsd +} + +define i32 @dosub(i32 %a, i32 %b) +{ + ; CHECK: dosub: + %tmp.0 = sub i32 %a, %b + ret i32 %tmp.0 + ; CHECK: rtsd +} + +define i32 @domul(i32 %a, i32 %b) +{ + ; CHECK: domul: + %tmp.0 = mul i32 %a, %b + ret i32 %tmp.0 + ; CHECK: rtsd +} + +define i32 @dodiv(i32 %a, i32 %b) +{ + ; CHECK: dodiv: + %tmp.0 = sdiv i32 %a, %b + ret i32 %tmp.0 + ; CHECK: rtsd +} + +define i32 @dorem(i32 %a, i32 %b) +{ + ; CHECK: dorem: + %tmp.0 = srem i32 %a, %b + ret i32 %tmp.0 + ; CHECK: rtsd +} + +define i32 @callind(i32 %a, i32 %b) +{ + ; CHECK: callind: +entry: + br label %loop + +loop: + %tmp.0 = phi i32 [ 0, %entry ], [ %tmp.3, %loop ] + %dst.0 = getelementptr [5 x i32 (i32,i32)*]* @FUNS, i32 0, i32 %tmp.0 + %dst.1 = load i32 (i32,i32)** %dst.0 + %tmp.1 = call i32 %dst.1(i32 %a, i32 %b) + ; CHECK-NOT: brli + ; CHECK-NOT: brlai + ; CHECK: brl + + call i32 (i8*,...)* @printf( i8* getelementptr([13 x i8]* @MSG,i32 0,i32 0), + i32 %tmp.1) + ; CHECK: brl + + %tmp.2 = add i32 %tmp.0, 1 + %tmp.3 = urem i32 %tmp.2, 5 + + br label %loop + ; CHECK: br +} diff --git a/test/CodeGen/MBlaze/cc.ll b/test/CodeGen/MBlaze/cc.ll new file mode 100644 index 0000000000..de55728e24 --- /dev/null +++ b/test/CodeGen/MBlaze/cc.ll @@ -0,0 +1,315 @@ +; Test some of the calling convention lowering done by the MBlaze backend. +; We test that integer values are passed in the correct registers and +; returned in the correct registers. Additionally, we test that the stack +; is used as appropriate for passing arguments that cannot be placed into +; registers. +; +; RUN: llc < %s -march=mblaze | FileCheck %s + +declare i32 @printf(i8*, ...) +@MSG = internal constant [13 x i8] c"Message: %d\0A\00" + +define void @params0_noret() { + ; CHECK: params0_noret: + ret void + ; CHECK-NOT: {{.* r3, r0, 1}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i8 @params0_8bitret() { + ; CHECK: params0_8bitret: + ret i8 1 + ; CHECK: {{.* r3, r0, 1}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i16 @params0_16bitret() { + ; CHECK: params0_16bitret: + ret i16 1 + ; CHECK: {{.* r3, r0, 1}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params0_32bitret() { + ; CHECK: params0_32bitret: + ret i32 1 + ; CHECK: {{.* r3, r0, 1}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i64 @params0_64bitret() { + ; CHECK: params0_64bitret: + ret i64 1 + ; CHECK: {{.* r3, r0, .*}} + ; CHECK: {{.* r4, r0, 1}} + ; CHECK: rtsd +} + +define i32 @params1_32bitret(i32 %a) { + ; CHECK: params1_32bitret: + ret i32 %a + ; CHECK: {{.* r3, r5, r0}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params2_32bitret(i32 %a, i32 %b) { + ; CHECK: params2_32bitret: + ret i32 %b + ; CHECK: {{.* r3, r6, r0}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params3_32bitret(i32 %a, i32 %b, i32 %c) { + ; CHECK: params3_32bitret: + ret i32 %c + ; CHECK: {{.* r3, r7, r0}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params4_32bitret(i32 %a, i32 %b, i32 %c, i32 %d) { + ; CHECK: params4_32bitret: + ret i32 %d + ; CHECK: {{.* r3, r8, r0}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params5_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) { + ; CHECK: params5_32bitret: + ret i32 %e + ; CHECK: {{.* r3, r9, r0}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params6_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) { + ; CHECK: params6_32bitret: + ret i32 %f + ; CHECK: {{.* r3, r10, r0}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params7_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, + i32 %g) { + ; CHECK: params7_32bitret: + ret i32 %g + ; CHECK: {{lwi? r3, r1, 8}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params8_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, + i32 %g, i32 %h) { + ; CHECK: params8_32bitret: + ret i32 %h + ; CHECK: {{lwi? r3, r1, 12}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params9_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, + i32 %g, i32 %h, i32 %i) { + ; CHECK: params9_32bitret: + ret i32 %i + ; CHECK: {{lwi? r3, r1, 16}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define i32 @params10_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, + i32 %g, i32 %h, i32 %i, i32 %j) { + ; CHECK: params10_32bitret: + ret i32 %j + ; CHECK: {{lwi? r3, r1, 20}} + ; CHECK-NOT: {{.* r4, .*, .*}} + ; CHECK: rtsd +} + +define void @testing() { + %MSG.1 = getelementptr [13 x i8]* @MSG, i32 0, i32 0 + + call void @params0_noret() + ; CHECK: brlid + + %tmp.1 = call i8 @params0_8bitret() + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i8 %tmp.1) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.2 = call i16 @params0_16bitret() + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i16 %tmp.2) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.3 = call i32 @params0_32bitret() + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.3) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.4 = call i64 @params0_64bitret() + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i64 %tmp.4) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK: {{.* r7, r4, r0}} + ; CHECK: brlid + + %tmp.5 = call i32 @params1_32bitret(i32 1) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.5) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.6 = call i32 @params2_32bitret(i32 1, i32 2) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.6) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.7 = call i32 @params3_32bitret(i32 1, i32 2, i32 3) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.7) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.8 = call i32 @params4_32bitret(i32 1, i32 2, i32 3, i32 4) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.8) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.9 = call i32 @params5_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: {{.* r9, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.9) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.10 = call i32 @params6_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, + i32 6) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: {{.* r9, .*, .*}} + ; CHECK: {{.* r10, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.10) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.11 = call i32 @params7_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, + i32 6, i32 7) + ; CHECK: {{swi? .*, r1, 4}} + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: {{.* r9, .*, .*}} + ; CHECK: {{.* r10, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.11) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.12 = call i32 @params8_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, + i32 6, i32 7, i32 8) + ; CHECK: {{swi? .*, r1, 4}} + ; CHECK: {{swi? .*, r1, 8}} + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: {{.* r9, .*, .*}} + ; CHECK: {{.* r10, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.12) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.13 = call i32 @params9_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, + i32 6, i32 7, i32 8, i32 9) + ; CHECK: {{swi? .*, r1, 4}} + ; CHECK: {{swi? .*, r1, 8}} + ; CHECK: {{swi? .*, r1, 12}} + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: {{.* r9, .*, .*}} + ; CHECK: {{.* r10, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.13) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + %tmp.14 = call i32 @params10_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, + i32 6, i32 7, i32 8, i32 9, i32 10) + ; CHECK: {{swi? .*, r1, 4}} + ; CHECK: {{swi? .*, r1, 8}} + ; CHECK: {{swi? .*, r1, 12}} + ; CHECK: {{swi? .*, r1, 16}} + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, .*, .*}} + ; CHECK: {{.* r7, .*, .*}} + ; CHECK: {{.* r8, .*, .*}} + ; CHECK: {{.* r9, .*, .*}} + ; CHECK: {{.* r10, .*, .*}} + ; CHECK: brlid + call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.14) + ; CHECK: {{.* r5, .*, .*}} + ; CHECK: {{.* r6, r3, r0}} + ; CHECK-NOT: {{.* r7, .*, .*}} + ; CHECK: brlid + + ret void +} diff --git a/test/CodeGen/MBlaze/dg.exp b/test/CodeGen/MBlaze/dg.exp new file mode 100644 index 0000000000..bfd5e47157 --- /dev/null +++ b/test/CodeGen/MBlaze/dg.exp @@ -0,0 +1,5 @@ +load_lib llvm.exp + +if { [llvm_supports_target MBlaze] } { + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] +} diff --git a/test/CodeGen/MBlaze/div.ll b/test/CodeGen/MBlaze/div.ll new file mode 100644 index 0000000000..fae9830619 --- /dev/null +++ b/test/CodeGen/MBlaze/div.ll @@ -0,0 +1,75 @@ +; Ensure that multiplication is lowered to function calls when the multiplier +; unit is not available in the hardware and that function calls are not used +; when the multiplier unit is available in the hardware. +; +; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s +; RUN: llc < %s -march=mblaze -mattr=+div | FileCheck -check-prefix=DIV %s + +define i8 @test_i8(i8 %a, i8 %b) { + ; FUN: test_i8: + ; DIV: test_i8: + + %tmp.1 = udiv i8 %a, %b + ; FUN-NOT: idiv + ; FUN: brlid + ; DIV-NOT: brlid + ; DIV: idivu + + %tmp.2 = sdiv i8 %a, %b + ; FUN-NOT: idiv + ; FUN: brlid + ; DIV-NOT: brlid + ; DIV-NOT: idivu + ; DIV: idiv + + %tmp.3 = add i8 %tmp.1, %tmp.2 + ret i8 %tmp.3 + ; FUN: rtsd + ; DIV: rtsd +} + +define i16 @test_i16(i16 %a, i16 %b) { + ; FUN: test_i16: + ; DIV: test_i16: + + %tmp.1 = udiv i16 %a, %b + ; FUN-NOT: idiv + ; FUN: brlid + ; DIV-NOT: brlid + ; DIV: idivu + + %tmp.2 = sdiv i16 %a, %b + ; FUN-NOT: idiv + ; FUN: brlid + ; DIV-NOT: brlid + ; DIV-NOT: idivu + ; DIV: idiv + + %tmp.3 = add i16 %tmp.1, %tmp.2 + ret i16 %tmp.3 + ; FUN: rtsd + ; DIV: rtsd +} + +define i32 @test_i32(i32 %a, i32 %b) { + ; FUN: test_i32: + ; DIV: test_i32: + + %tmp.1 = udiv i32 %a, %b + ; FUN-NOT: idiv + ; FUN: brlid + ; DIV-NOT: brlid + ; DIV: idivu + + %tmp.2 = sdiv i32 %a, %b + ; FUN-NOT: idiv + ; FUN: brlid + ; DIV-NOT: brlid + ; DIV-NOT: idivu + ; DIV: idiv + + %tmp.3 = add i32 %tmp.1, %tmp.2 + ret i32 %tmp.3 + ; FUN: rtsd + ; DIV: rtsd +} diff --git a/test/CodeGen/MBlaze/fpu.ll b/test/CodeGen/MBlaze/fpu.ll new file mode 100644 index 0000000000..83f4d83124 --- /dev/null +++ b/test/CodeGen/MBlaze/fpu.ll @@ -0,0 +1,66 @@ +; Ensure that floating point operations are lowered to function calls when the +; FPU is not available in the hardware and that function calls are not used +; when the FPU is available in the hardware. +; +; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s +; RUN: llc < %s -march=mblaze -mattr=+fpu | FileCheck -check-prefix=FPU %s + +define float @test_add(float %a, float %b) { + ; FUN: test_add: + ; FPU: test_add: + + %tmp.1 = fadd float %a, %b + ; FUN-NOT: fadd + ; FUN: brlid + ; FPU-NOT: brlid + ; FPU: fadd + + ret float %tmp.1 + ; FUN: rtsd + ; FPU: rtsd +} + +define float @test_sub(float %a, float %b) { + ; FUN: test_sub: + ; FPU: test_sub: + + %tmp.1 = fsub float %a, %b + ; FUN-NOT: frsub + ; FUN: brlid + ; FPU-NOT: brlid + ; FPU: frsub + + ret float %tmp.1 + ; FUN: rtsd + ; FPU: rtsd +} + +define float @test_mul(float %a, float %b) { + ; FUN: test_mul: + ; FPU: test_mul: + + %tmp.1 = fmul float %a, %b + ; FUN-NOT: fmul + ; FUN: brlid + ; FPU-NOT: brlid + ; FPU: fmul + + ret float %tmp.1 + ; FUN: rtsd + ; FPU: rtsd +} + +define float @test_div(float %a, float %b) { + ; FUN: test_div: + ; FPU: test_div: + + %tmp.1 = fdiv float %a, %b + ; FUN-NOT: fdiv + ; FUN: brlid + ; FPU-NOT: brlid + ; FPU: fdiv + + ret float %tmp.1 + ; FUN: rtsd + ; FPU: rtsd +} diff --git a/test/CodeGen/MBlaze/fsl.ll b/test/CodeGen/MBlaze/fsl.ll new file mode 100644 index 0000000000..f9c6205bc1 --- /dev/null +++ b/test/CodeGen/MBlaze/fsl.ll @@ -0,0 +1,323 @@ +; Ensure that the FSL instrinsic instruction generate single FSL instructions +; at the machine level. Additionally, ensure that dynamic values use the +; dynamic version of the instructions and that constant values use the +; constant version of the instructions. +; +; RUN: llc < %s -march=mblaze | FileCheck %s + +declare i32 @llvm.mblaze.fsl.get(i32 %port) +declare i32 @llvm.mblaze.fsl.aget(i32 %port) +declare i32 @llvm.mblaze.fsl.cget(i32 %port) +declare i32 @llvm.mblaze.fsl.caget(i32 %port) +declare i32 @llvm.mblaze.fsl.eget(i32 %port) +declare i32 @llvm.mblaze.fsl.eaget(i32 %port) +declare i32 @llvm.mblaze.fsl.ecget(i32 %port) +declare i32 @llvm.mblaze.fsl.ecaget(i32 %port) +declare i32 @llvm.mblaze.fsl.nget(i32 %port) +declare i32 @llvm.mblaze.fsl.naget(i32 %port) +declare i32 @llvm.mblaze.fsl.ncget(i32 %port) +declare i32 @llvm.mblaze.fsl.ncaget(i32 %port) +declare i32 @llvm.mblaze.fsl.neget(i32 %port) +declare i32 @llvm.mblaze.fsl.neaget(i32 %port) +declare i32 @llvm.mblaze.fsl.necget(i32 %port) +declare i32 @llvm.mblaze.fsl.necaget(i32 %port) +declare i32 @llvm.mblaze.fsl.tget(i32 %port) +declare i32 @llvm.mblaze.fsl.taget(i32 %port) +declare i32 @llvm.mblaze.fsl.tcget(i32 %port) +declare i32 @llvm.mblaze.fsl.tcaget(i32 %port) +declare i32 @llvm.mblaze.fsl.teget(i32 %port) +declare i32 @llvm.mblaze.fsl.teaget(i32 %port) +declare i32 @llvm.mblaze.fsl.tecget(i32 %port) +declare i32 @llvm.mblaze.fsl.tecaget(i32 %port) +declare i32 @llvm.mblaze.fsl.tnget(i32 %port) +declare i32 @llvm.mblaze.fsl.tnaget(i32 %port) +declare i32 @llvm.mblaze.fsl.tncget(i32 %port) +declare i32 @llvm.mblaze.fsl.tncaget(i32 %port) +declare i32 @llvm.mblaze.fsl.tneget(i32 %port) +declare i32 @llvm.mblaze.fsl.tneaget(i32 %port) +declare i32 @llvm.mblaze.fsl.tnecget(i32 %port) +declare i32 @llvm.mblaze.fsl.tnecaget(i32 %port) + +declare void @llvm.mblaze.fsl.put(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.aput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.cput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.caput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.nput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.naput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.ncput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.ncaput(i32 %value, i32 %port) +declare void @llvm.mblaze.fsl.tput(i32 %port) +declare void @llvm.mblaze.fsl.taput(i32 %port) +declare void @llvm.mblaze.fsl.tcput(i32 %port) +declare void @llvm.mblaze.fsl.tcaput(i32 %port) +declare void @llvm.mblaze.fsl.tnput(i32 %port) +declare void @llvm.mblaze.fsl.tnaput(i32 %port) +declare void @llvm.mblaze.fsl.tncput(i32 %port) +declare void @llvm.mblaze.fsl.tncaput(i32 %port) + +define i32 @fsl_get(i32 %port) +{ + ; CHECK: fsl_get: + %v0 = call i32 @llvm.mblaze.fsl.get(i32 %port) + ; CHECK: getd + %v1 = call i32 @llvm.mblaze.fsl.aget(i32 %port) + ; CHECK-NEXT: agetd + %v2 = call i32 @llvm.mblaze.fsl.cget(i32 %port) + ; CHECK-NEXT: cgetd + %v3 = call i32 @llvm.mblaze.fsl.caget(i32 %port) + ; CHECK-NEXT: cagetd + %v4 = call i32 @llvm.mblaze.fsl.eget(i32 %port) + ; CHECK-NEXT: egetd + %v5 = call i32 @llvm.mblaze.fsl.eaget(i32 %port) + ; CHECK-NEXT: eagetd + %v6 = call i32 @llvm.mblaze.fsl.ecget(i32 %port) + ; CHECK-NEXT: ecgetd + %v7 = call i32 @llvm.mblaze.fsl.ecaget(i32 %port) + ; CHECK-NEXT: ecagetd + %v8 = call i32 @llvm.mblaze.fsl.nget(i32 %port) + ; CHECK-NEXT: ngetd + %v9 = call i32 @llvm.mblaze.fsl.naget(i32 %port) + ; CHECK-NEXT: nagetd + %v10 = call i32 @llvm.mblaze.fsl.ncget(i32 %port) + ; CHECK-NEXT: ncgetd + %v11 = call i32 @llvm.mblaze.fsl.ncaget(i32 %port) + ; CHECK-NEXT: ncagetd + %v12 = call i32 @llvm.mblaze.fsl.neget(i32 %port) + ; CHECK-NEXT: negetd + %v13 = call i32 @llvm.mblaze.fsl.neaget(i32 %port) + ; CHECK-NEXT: neagetd + %v14 = call i32 @llvm.mblaze.fsl.necget(i32 %port) + ; CHECK-NEXT: necgetd + %v15 = call i32 @llvm.mblaze.fsl.necaget(i32 %port) + ; CHECK-NEXT: necagetd + %v16 = call i32 @llvm.mblaze.fsl.tget(i32 %port) + ; CHECK-NEXT: tgetd + %v17 = call i32 @llvm.mblaze.fsl.taget(i32 %port) + ; CHECK-NEXT: tagetd + %v18 = call i32 @llvm.mblaze.fsl.tcget(i32 %port) + ; CHECK-NEXT: tcgetd + %v19 = call i32 @llvm.mblaze.fsl.tcaget(i32 %port) + ; CHECK-NEXT: tcagetd + %v20 = call i32 @llvm.mblaze.fsl.teget(i32 %port) + ; CHECK-NEXT: tegetd + %v21 = call i32 @llvm.mblaze.fsl.teaget(i32 %port) + ; CHECK-NEXT: teagetd + %v22 = call i32 @llvm.mblaze.fsl.tecget(i32 %port) + ; CHECK-NEXT: tecgetd + %v23 = call i32 @llvm.mblaze.fsl.tecaget(i32 %port) + ; CHECK-NEXT: tecagetd + %v24 = call i32 @llvm.mblaze.fsl.tnget(i32 %port) + ; CHECK-NEXT: tngetd + %v25 = call i32 @llvm.mblaze.fsl.tnaget(i32 %port) + ; CHECK-NEXT: tnagetd + %v26 = call i32 @llvm.mblaze.fsl.tncget(i32 %port) + ; CHECK-NEXT: tncgetd + %v27 = call i32 @llvm.mblaze.fsl.tncaget(i32 %port) + ; CHECK-NEXT: tncagetd + %v28 = call i32 @llvm.mblaze.fsl.tneget(i32 %port) + ; CHECK-NEXT: tnegetd + %v29 = call i32 @llvm.mblaze.fsl.tneaget(i32 %port) + ; CHECK-NEXT: tneagetd + %v30 = call i32 @llvm.mblaze.fsl.tnecget(i32 %port) + ; CHECK-NEXT: tnecgetd + %v31 = call i32 @llvm.mblaze.fsl.tnecaget(i32 %port) + ; CHECK-NEXT: tnecagetd + ret i32 1 + ; CHECK: rtsd +} + +define i32 @fslc_get() +{ + ; CHECK: fslc_get: + %v0 = call i32 @llvm.mblaze.fsl.get(i32 1) + ; CHECK: get + %v1 = call i32 @llvm.mblaze.fsl.aget(i32 1) + ; CHECK-NOT: agetd + ; CHECK: aget + %v2 = call i32 @llvm.mblaze.fsl.cget(i32 1) + ; CHECK-NOT: cgetd + ; CHECK: cget + %v3 = call i32 @llvm.mblaze.fsl.caget(i32 1) + ; CHECK-NOT: cagetd + ; CHECK: caget + %v4 = call i32 @llvm.mblaze.fsl.eget(i32 1) + ; CHECK-NOT: egetd + ; CHECK: eget + %v5 = call i32 @llvm.mblaze.fsl.eaget(i32 1) + ; CHECK-NOT: eagetd + ; CHECK: eaget + %v6 = call i32 @llvm.mblaze.fsl.ecget(i32 1) + ; CHECK-NOT: ecgetd + ; CHECK: ecget + %v7 = call i32 @llvm.mblaze.fsl.ecaget(i32 1) + ; CHECK-NOT: ecagetd + ; CHECK: ecaget + %v8 = call i32 @llvm.mblaze.fsl.nget(i32 1) + ; CHECK-NOT: ngetd + ; CHECK: nget + %v9 = call i32 @llvm.mblaze.fsl.naget(i32 1) + ; CHECK-NOT: nagetd + ; CHECK: naget + %v10 = call i32 @llvm.mblaze.fsl.ncget(i32 1) + ; CHECK-NOT: ncgetd + ; CHECK: ncget + %v11 = call i32 @llvm.mblaze.fsl.ncaget(i32 1) + ; CHECK-NOT: ncagetd + ; CHECK: ncaget + %v12 = call i32 @llvm.mblaze.fsl.neget(i32 1) + ; CHECK-NOT: negetd + ; CHECK: neget + %v13 = call i32 @llvm.mblaze.fsl.neaget(i32 1) + ; CHECK-NOT: neagetd + ; CHECK: neaget + %v14 = call i32 @llvm.mblaze.fsl.necget(i32 1) + ; CHECK-NOT: necgetd + ; CHECK: necget + %v15 = call i32 @llvm.mblaze.fsl.necaget(i32 1) + ; CHECK-NOT: necagetd + ; CHECK: necaget + %v16 = call i32 @llvm.mblaze.fsl.tget(i32 1) + ; CHECK-NOT: tgetd + ; CHECK: tget + %v17 = call i32 @llvm.mblaze.fsl.taget(i32 1) + ; CHECK-NOT: tagetd + ; CHECK: taget + %v18 = call i32 @llvm.mblaze.fsl.tcget(i32 1) + ; CHECK-NOT: tcgetd + ; CHECK: tcget + %v19 = call i32 @llvm.mblaze.fsl.tcaget(i32 1) + ; CHECK-NOT: tcagetd + ; CHECK: tcaget + %v20 = call i32 @llvm.mblaze.fsl.teget(i32 1) + ; CHECK-NOT: tegetd + ; CHECK: teget + %v21 = call i32 @llvm.mblaze.fsl.teaget(i32 1) + ; CHECK-NOT: teagetd + ; CHECK: teaget + %v22 = call i32 @llvm.mblaze.fsl.tecget(i32 1) + ; CHECK-NOT: tecgetd + ; CHECK: tecget + %v23 = call i32 @llvm.mblaze.fsl.tecaget(i32 1) + ; CHECK-NOT: tecagetd + ; CHECK: tecaget + %v24 = call i32 @llvm.mblaze.fsl.tnget(i32 1) + ; CHECK-NOT: tngetd + ; CHECK: tnget + %v25 = call i32 @llvm.mblaze.fsl.tnaget(i32 1) + ; CHECK-NOT: tnagetd + ; CHECK: tnaget + %v26 = call i32 @llvm.mblaze.fsl.tncget(i32 1) + ; CHECK-NOT: tncgetd + ; CHECK: tncget + %v27 = call i32 @llvm.mblaze.fsl.tncaget(i32 1) + ; CHECK-NOT: tncagetd + ; CHECK: tncaget + %v28 = call i32 @llvm.mblaze.fsl.tneget(i32 1) + ; CHECK-NOT: tnegetd + ; CHECK: tneget + %v29 = call i32 @llvm.mblaze.fsl.tneaget(i32 1) + ; CHECK-NOT: tneagetd + ; CHECK: tneaget + %v30 = call i32 @llvm.mblaze.fsl.tnecget(i32 1) + ; CHECK-NOT: tnecgetd + ; CHECK: tnecget + %v31 = call i32 @llvm.mblaze.fsl.tnecaget(i32 1) + ; CHECK-NOT: tnecagetd + ; CHECK: tnecaget + ret i32 1 + ; CHECK: rtsd +} + +define void @putfsl(i32 %value, i32 %port) +{ + ; CHECK: putfsl: + call void @llvm.mblaze.fsl.put(i32 %value, i32 %port) + ; CHECK: putd + call void @llvm.mblaze.fsl.aput(i32 %value, i32 %port) + ; CHECK-NEXT: aputd + call void @llvm.mblaze.fsl.cput(i32 %value, i32 %port) + ; CHECK-NEXT: cputd + call void @llvm.mblaze.fsl.caput(i32 %value, i32 %port) + ; CHECK-NEXT: caputd + call void @llvm.mblaze.fsl.nput(i32 %value, i32 %port) + ; CHECK-NEXT: nputd + call void @llvm.mblaze.fsl.naput(i32 %value, i32 %port) + ; CHECK-NEXT: naputd + call void @llvm.mblaze.fsl.ncput(i32 %value, i32 %port) + ; CHECK-NEXT: ncputd + call void @llvm.mblaze.fsl.ncaput(i32 %value, i32 %port) + ; CHECK-NEXT: ncaputd + call void @llvm.mblaze.fsl.tput(i32 %port) + ; CHECK-NEXT: tputd + call void @llvm.mblaze.fsl.taput(i32 %port) + ; CHECK-NEXT: taputd + call void @llvm.mblaze.fsl.tcput(i32 %port) + ; CHECK-NEXT: tcputd + call void @llvm.mblaze.fsl.tcaput(i32 %port) + ; CHECK-NEXT: tcaputd + call void @llvm.mblaze.fsl.tnput(i32 %port) + ; CHECK-NEXT: tnputd + call void @llvm.mblaze.fsl.tnaput(i32 %port) + ; CHECK-NEXT: tnaputd + call void @llvm.mblaze.fsl.tncput(i32 %port) + ; CHECK-NEXT: tncputd + call void @llvm.mblaze.fsl.tncaput(i32 %port) + ; CHECK-NEXT: tncaputd + ret void + ; CHECK: rtsd +} + +define void @putfsl_const(i32 %value) +{ + ; CHECK: putfsl_const: + call void @llvm.mblaze.fsl.put(i32 %value, i32 1) + ; CHECK-NOT: putd + ; CHECK: put + call void @llvm.mblaze.fsl.aput(i32 %value, i32 1) + ; CHECK-NOT: aputd + ; CHECK: aput + call void @llvm.mblaze.fsl.cput(i32 %value, i32 1) + ; CHECK-NOT: cputd + ; CHECK: cput + call void @llvm.mblaze.fsl.caput(i32 %value, i32 1) + ; CHECK-NOT: caputd + ; CHECK: caput + call void @llvm.mblaze.fsl.nput(i32 %value, i32 1) + ; CHECK-NOT: nputd + ; CHECK: nput + call void @llvm.mblaze.fsl.naput(i32 %value, i32 1) + ; CHECK-NOT: naputd + ; CHECK: naput + call void @llvm.mblaze.fsl.ncput(i32 %value, i32 1) + ; CHECK-NOT: ncputd + ; CHECK: ncput + call void @llvm.mblaze.fsl.ncaput(i32 %value, i32 1) + ; CHECK-NOT: ncaputd + ; CHECK: ncaput + call void @llvm.mblaze.fsl.tput(i32 1) + ; CHECK-NOT: tputd + ; CHECK: tput + call void @llvm.mblaze.fsl.taput(i32 1) + ; CHECK-NOT: taputd + ; CHECK: taput + call void @llvm.mblaze.fsl.tcput(i32 1) + ; CHECK-NOT: tcputd + ; CHECK: tcput + call void @llvm.mblaze.fsl.tcaput(i32 1) + ; CHECK-NOT: tcaputd + ; CHECK: tcaput + call void @llvm.mblaze.fsl.tnput(i32 1) + ; CHECK-NOT: tnputd + ; CHECK: tnput + call void @llvm.mblaze.fsl.tnaput(i32 1) + ; CHECK-NOT: tnaputd + ; CHECK: tnaput + call void @llvm.mblaze.fsl.tncput(i32 1) + ; CHECK-NOT: tncputd + ; CHECK: tncput + call void @llvm.mblaze.fsl.tncaput(i32 1) + ; CHECK-NOT: tncaputd + ; CHECK: tncaput + ret void + ; CHECK: rtsd +} diff --git a/test/CodeGen/MBlaze/imm.ll b/test/CodeGen/MBlaze/imm.ll new file mode 100644 index 0000000000..85fad175b7 --- /dev/null +++ b/test/CodeGen/MBlaze/imm.ll @@ -0,0 +1,70 @@ +; Ensure that all immediate values that are 32-bits or less can be loaded +; using a single instruction and that immediate values 64-bits or less can +; be loaded using two instructions. +; +; RUN: llc < %s -march=mblaze | FileCheck %s +; RUN: llc < %s -march=mblaze -mattr=+fpu | FileCheck -check-prefix=FPU %s + +define i8 @retimm_i8() { + ; CHECK: retimm_i8: + ; CHECK: add + ; CHECK-NEXT: rtsd + ; FPU: retimm_i8: + ; FPU: add + ; FPU-NEXT: rtsd + ret i8 123 +} + +define i16 @retimm_i16() { + ; CHECK: retimm_i16: + ; CHECK: add + ; CHECK-NEXT: rtsd + ; FPU: retimm_i16: + ; FPU: add + ; FPU-NEXT: rtsd + ret i16 38212 +} + +define i32 @retimm_i32() { + ; CHECK: retimm_i32: + ; CHECK: add + ; CHECK-NEXT: rtsd + ; FPU: retimm_i32: + ; FPU: add + ; FPU-NEXT: rtsd + ret i32 2938128 +} + +define i64 @retimm_i64() { + ; CHECK: retimm_i64: + ; CHECK: add + ; CHECK-NEXT: add + ; CHECK-NEXT: rtsd + ; FPU: retimm_i64: + ; FPU: add + ; FPU-NEXT: add + ; FPU-NEXT: rtsd + ret i64 94581823 +} + +define float @retimm_float() { + ; CHECK: retimm_float: + ; CHECK: add + ; CHECK-NEXT: rtsd + ; FPU: retimm_float: + ; FPU: or + ; FPU: rtsd + ret float 12.0 +} + +define double @retimm_double() { + ; CHECK: retimm_double: + ; CHECK: add + ; CHECK-NEXT: add + ; CHECK-NEXT: rtsd + ; FPU: retimm_double: + ; FPU: add + ; FPU-NEXT: add + ; FPU-NEXT: rtsd + ret double 598382.39283873 +} diff --git a/test/CodeGen/MBlaze/jumptable.ll b/test/CodeGen/MBlaze/jumptable.ll new file mode 100644 index 0000000000..3f27c12f19 --- /dev/null +++ b/test/CodeGen/MBlaze/jumptable.ll @@ -0,0 +1,79 @@ +; Ensure that jump tables can be handled by the mblaze backend. The +; jump table should be lowered to a "br" instruction using one of the +; available registers. +; +; RUN: llc < %s -march=mblaze | FileCheck %s + +define i32 @jmptable(i32 %arg) +{ + ; CHECK: jmptable: + switch i32 %arg, label %DEFAULT [ i32 0, label %L0 + i32 1, label %L1 + i32 2, label %L2 + i32 3, label %L3 + i32 4, label %L4 + i32 5, label %L5 + i32 6, label %L6 + i32 7, label %L7 + i32 8, label %L8 + i32 9, label %L9 ] + + ; CHECK: lw [[REG:r[0-9]*]] + ; CHECK: br [[REG]] +L0: + %var0 = add i32 %arg, 0 + br label %DONE + +L1: + %var1 = add i32 %arg, 1 + br label %DONE + +L2: + %var2 = add i32 %arg, 2 + br label %DONE + +L3: + %var3 = add i32 %arg, 3 + br label %DONE + +L4: + %var4 = add i32 %arg, 4 + br label %DONE + +L5: + %var5 = add i32 %arg, 5 + br label %DONE + +L6: + %var6 = add i32 %arg, 6 + br label %DONE + +L7: + %var7 = add i32 %arg, 7 + br label %DONE + +L8: + %var8 = add i32 %arg, 8 + br label %DONE + +L9: + %var9 = add i32 %arg, 9 + br label %DONE + +DEFAULT: + unreachable + +DONE: + %rval = phi i32 [ %var0, %L0 ], + [ %var1, %L1 ], + [ %var2, %L2 ], + [ %var3, %L3 ], + [ %var4, %L4 ], + [ %var5, %L5 ], + [ %var6, %L6 ], + [ %var7, %L7 ], + [ %var8, %L8 ], + [ %var9, %L9 ] + ret i32 %rval + ; CHECK: rtsd +} diff --git a/test/CodeGen/MBlaze/loop.ll b/test/CodeGen/MBlaze/loop.ll new file mode 100644 index 0000000000..b473020e66 --- /dev/null +++ b/test/CodeGen/MBlaze/loop.ll @@ -0,0 +1,47 @@ +; Test some complicated looping constructs to ensure that they +; compile successfully and that some sort of branching is used +; in the resulting code. +; +; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s + +declare i32 @printf(i8*, ...) +@MSG = internal constant [19 x i8] c"Message: %d %d %d\0A\00" + +define i32 @loop(i32 %a, i32 %b) +{ + ; CHECK: loop: +entry: + br label %loop_outer + +loop_outer: + %outer.0 = phi i32 [ 0, %entry ], [ %outer.2, %loop_outer_finish ] + br label %loop_inner + +loop_inner: + %inner.0 = phi i32 [ %a, %loop_outer ], [ %inner.3, %loop_inner_finish ] + %inner.1 = phi i32 [ %b, %loop_outer ], [ %inner.4, %loop_inner_finish ] + %inner.2 = phi i32 [ 0, %loop_outer ], [ %inner.5, %loop_inner_finish ] + %inner.3 = add i32 %inner.0, %inner.1 + %inner.4 = mul i32 %inner.2, 11 + br label %loop_inner_finish + +loop_inner_finish: + %inner.5 = add i32 %inner.2, 1 + ; CHECK: addi {{.*, 1}} + + call i32 (i8*,...)* @printf( i8* getelementptr([19 x i8]* @MSG,i32 0,i32 0), + i32 %inner.0, i32 %inner.1, i32 %inner.2 ) + ; CHECK: brlid + + %inner.6 = icmp eq i32 %inner.5, 100 + ; CHECK: cmp + + br i1 %inner.6, label %loop_inner, label %loop_outer_finish + ; CHECK: {{beq|bne}} + +loop_outer_finish: + %outer.1 = add i32 %outer.0, 1 + %outer.2 = urem i32 %outer.1, 1500 + br label %loop_outer + ; CHECK: br +} diff --git a/test/CodeGen/MBlaze/mul.ll b/test/CodeGen/MBlaze/mul.ll new file mode 100644 index 0000000000..65d3e22a3e --- /dev/null +++ b/test/CodeGen/MBlaze/mul.ll @@ -0,0 +1,51 @@ +; Ensure that multiplication is lowered to function calls when the multiplier +; unit is not available in the hardware and that function calls are not used +; when the multiplier unit is available in the hardware. +; +; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s +; RUN: llc < %s -march=mblaze -mattr=+mul | FileCheck -check-prefix=MUL %s + +define i8 @test_i8(i8 %a, i8 %b) { + ; FUN: test_i8: + ; MUL: test_i8: + + %tmp.1 = mul i8 %a, %b + ; FUN-NOT: mul + ; FUN: brlid + ; MUL-NOT: brlid + ; MUL: mul + + ret i8 %tmp.1 + ; FUN: rtsd + ; MUL: rtsd +} + +define i16 @test_i16(i16 %a, i16 %b) { + ; FUN: test_i16: + ; MUL: test_i16: + + %tmp.1 = mul i16 %a, %b + ; FUN-NOT: mul + ; FUN: brlid + ; MUL-NOT: brlid + ; MUL: mul + + ret i16 %tmp.1 + ; FUN: rtsd + ; MUL: rtsd +} + +define i32 @test_i32(i32 %a, i32 %b) { + ; FUN: test_i32: + ; MUL: test_i32: + + %tmp.1 = mul i32 %a, %b + ; FUN-NOT: mul + ; FUN: brlid + ; MUL-NOT: brlid + ; MUL: mul + + ret i32 %tmp.1 + ; FUN: rtsd + ; MUL: rtsd +} diff --git a/test/CodeGen/MBlaze/mul64.ll b/test/CodeGen/MBlaze/mul64.ll new file mode 100644 index 0000000000..e0ef4138af --- /dev/null +++ b/test/CodeGen/MBlaze/mul64.ll @@ -0,0 +1,23 @@ +; Ensure that multiplication is lowered to function calls when the 64-bit +; multiplier unit is not available in the hardware and that function calls +; are not used when the 64-bit multiplier unit is available in the hardware. +; +; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s +; RUN: llc < %s -march=mblaze -mattr=+mul,+mul64 | \ +; RUN: FileCheck -check-prefix=MUL %s + +define i64 @test_i64(i64 %a, i64 %b) { + ; FUN: test_i64: + ; MUL: test_i64: + + %tmp.1 = mul i64 %a, %b + ; FUN-NOT: mul + ; FUN: brlid + ; MUL-NOT: brlid + ; MUL: mulh + ; MUL: mul + + ret i64 %tmp.1 + ; FUN: rtsd + ; MUL: rtsd +} diff --git a/test/CodeGen/MBlaze/select.ll b/test/CodeGen/MBlaze/select.ll new file mode 100644 index 0000000000..47a88a1e3c --- /dev/null +++ b/test/CodeGen/MBlaze/select.ll @@ -0,0 +1,15 @@ +; Ensure that the select instruction is supported and is lowered to +; some sort of branch instruction. +; +; RUN: llc < %s -march=mblaze | FileCheck %s + +define i32 @testsel(i32 %a, i32 %b) +{ + ; CHECK: testsel: + %tmp.1 = icmp eq i32 %a, %b + ; CHECK: cmp + %tmp.2 = select i1 %tmp.1, i32 %a, i32 %b + ; CHECK: {{bne|beq}} + ret i32 %tmp.2 + ; CHECK: rtsd +} diff --git a/test/CodeGen/MBlaze/shift.ll b/test/CodeGen/MBlaze/shift.ll new file mode 100644 index 0000000000..186115ec19 --- /dev/null +++ b/test/CodeGen/MBlaze/shift.ll @@ -0,0 +1,117 @@ +; Ensure that shifts are lowered to loops when the barrel shifter unit is +; not available in the hardware and that loops are not used when the +; barrel shifter unit is available in the hardware. +; +; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s +; RUN: llc < %s -march=mblaze -mattr=+barrel | FileCheck -check-prefix=SHT %s + +define i8 @test_i8(i8 %a, i8 %b) { + ; FUN: test_i8: + ; SHT: test_i8: + + %tmp.1 = shl i8 %a, %b + ; FUN-NOT: bsll + ; FUN: andi + ; FUN: add + ; FUN: bnei + ; SHT-NOT: andi + ; SHT-NOT: bnei + ; SHT: bsll + + ret i8 %tmp.1 + ; FUN: rtsd + ; SHT: rtsd +} + +define i8 @testc_i8(i8 %a, i8 %b) { + ; FUN: testc_i8: + ; SHT: testc_i8: + + %tmp.1 = shl i8 %a, 5 + ; FUN-NOT: bsll + ; FUN: andi + ; FUN: add + ; FUN: bnei + ; SHT-NOT: andi + ; SHT-NOT: add + ; SHT-NOT: bnei + ; SHT: bslli + + ret i8 %tmp.1 + ; FUN: rtsd + ; SHT: rtsd +} + +define i16 @test_i16(i16 %a, i16 %b) { + ; FUN: test_i16: + ; SHT: test_i16: + + %tmp.1 = shl i16 %a, %b + ; FUN-NOT: bsll + ; FUN: andi + ; FUN: add + ; FUN: bnei + ; SHT-NOT: andi + ; SHT-NOT: bnei + ; SHT: bsll + + ret i16 %tmp.1 + ; FUN: rtsd + ; SHT: rtsd +} + +define i16 @testc_i16(i16 %a, i16 %b) { + ; FUN: testc_i16: + ; SHT: testc_i16: + + %tmp.1 = shl i16 %a, 5 + ; FUN-NOT: bsll + ; FUN: andi + ; FUN: add + ; FUN: bnei + ; SHT-NOT: andi + ; SHT-NOT: add + ; SHT-NOT: bnei + ; SHT: bslli + + ret i16 %tmp.1 + ; FUN: rtsd + ; SHT: rtsd +} + +define i32 @test_i32(i32 %a, i32 %b) { + ; FUN: test_i32: + ; SHT: test_i32: + + %tmp.1 = shl i32 %a, %b + ; FUN-NOT: bsll + ; FUN: andi + ; FUN: add + ; FUN: bnei + ; SHT-NOT: andi + ; SHT-NOT: bnei + ; SHT: bsll + + ret i32 %tmp.1 + ; FUN: rtsd + ; SHT: rtsd +} + +define i32 @testc_i32(i32 %a, i32 %b) { + ; FUN: testc_i32: + ; SHT: testc_i32: + + %tmp.1 = shl i32 %a, 5 + ; FUN-NOT: bsll + ; FUN: andi + ; FUN: add + ; FUN: bnei + ; SHT-NOT: andi + ; SHT-NOT: add + ; SHT-NOT: bnei + ; SHT: bslli + + ret i32 %tmp.1 + ; FUN: rtsd + ; SHT: rtsd +} |