aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp11
-rw-r--r--test/CodeGen/Mips/inlineasm-operand-code.ll185
2 files changed, 131 insertions, 65 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 914a204fe2..00ff7545c1 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -355,6 +355,7 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
}
case 'D': // Second part of a double word register operand
case 'L': // Low order register of a double word register operand
+ case 'M': // High order register of a double word register operand
{
if (OpNum == 0)
return true;
@@ -377,12 +378,16 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned RegOp = OpNum;
if (!Subtarget->isGP64bit()){
// Endianess reverses which register holds the high or low value
+ // between M and L.
switch(ExtraCode[0]) {
- case 'D':
- RegOp = (Subtarget->isLittle()) ? OpNum : OpNum+1;
+ case 'M':
+ RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
break;
case 'L':
- RegOp = (Subtarget->isLittle()) ? OpNum+1 : OpNum;
+ RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
+ break;
+ case 'D': // Always the second part
+ RegOp = OpNum + 1;
}
if (RegOp >= MI->getNumOperands())
return true;
diff --git a/test/CodeGen/Mips/inlineasm-operand-code.ll b/test/CodeGen/Mips/inlineasm-operand-code.ll
index 97ec629db2..01978994b2 100644
--- a/test/CodeGen/Mips/inlineasm-operand-code.ll
+++ b/test/CodeGen/Mips/inlineasm-operand-code.ll
@@ -1,92 +1,153 @@
; Positive test for inline register constraints
;
-; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=LITTLE
-; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=BIG
+; RUN: llc -march=mipsel < %s | FileCheck -check-prefix=CHECK_LITTLE_32 %s
+; RUN: llc -march=mips < %s | FileCheck -check-prefix=CHECK_BIG_32 %s
%union.u_tag = type { i64 }
%struct.anon = type { i32, i32 }
@uval = common global %union.u_tag zeroinitializer, align 8
-define i32 @main() nounwind {
-entry:
; X with -3
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},0xfffffffffffffffd
-;LITTLE: #NO_APP
- tail call i32 asm sideeffect "addi $0,$1,${2:X}", "=r,r,I"(i32 7, i32 -3) nounwind
+define i32 @constraint_X() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_X:
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},0xfffffffffffffffd
+;CHECK_LITTLE_32: #NO_APP
+ tail call i32 asm sideeffect "addi $0,$1,${2:X}", "=r,r,I"(i32 7, i32 -3) ;
+ ret i32 0
+}
; x with -3
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},0xfffd
-;LITTLE: #NO_APP
- tail call i32 asm sideeffect "addi $0,$1,${2:x}", "=r,r,I"(i32 7, i32 -3) nounwind
+define i32 @constraint_x() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_x:
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},0xfffd
+;CHECK_LITTLE_32: #NO_APP
+ tail call i32 asm sideeffect "addi $0,$1,${2:x}", "=r,r,I"(i32 7, i32 -3) ;
+ ret i32 0
+}
; d with -3
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},-3
-;LITTLE: #NO_APP
- tail call i32 asm sideeffect "addi $0,$1,${2:d}", "=r,r,I"(i32 7, i32 -3) nounwind
+define i32 @constraint_d() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_d:
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},-3
+;CHECK_LITTLE_32: #NO_APP
+ tail call i32 asm sideeffect "addi $0,$1,${2:d}", "=r,r,I"(i32 7, i32 -3) ;
+ ret i32 0
+}
; m with -3
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},-4
-;LITTLE: #NO_APP
- tail call i32 asm sideeffect "addi $0,$1,${2:m}", "=r,r,I"(i32 7, i32 -3) nounwind
+define i32 @constraint_m() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_m:
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},-4
+;CHECK_LITTLE_32: #NO_APP
+ tail call i32 asm sideeffect "addi $0,$1,${2:m}", "=r,r,I"(i32 7, i32 -3) ;
+ ret i32 0
+}
; z with -3
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},-3
-;LITTLE: #NO_APP
- tail call i32 asm sideeffect "addi $0,$1,${2:z}", "=r,r,I"(i32 7, i32 -3) nounwind
+define i32 @constraint_z() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_z:
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},-3
+;CHECK_LITTLE_32: #NO_APP
+ tail call i32 asm sideeffect "addi $0,$1,${2:z}", "=r,r,I"(i32 7, i32 -3) ;
; z with 0
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},$0
-;LITTLE: #NO_APP
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},$0
+;CHECK_LITTLE_32: #NO_APP
tail call i32 asm sideeffect "addi $0,$1,${2:z}", "=r,r,I"(i32 7, i32 0) nounwind
+ ret i32 0
+}
; a long long in 32 bit mode (use to assert)
-;LITTLE: #APP
-;LITTLE: addi ${{[0-9]+}},${{[0-9]+}},3
-;LITTLE: #NO_APP
+define i32 @constraint_longlong() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_longlong:
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: addi ${{[0-9]+}},${{[0-9]+}},3
+;CHECK_LITTLE_32: #NO_APP
tail call i64 asm sideeffect "addi $0,$1,$2 \0A\09", "=r,r,X"(i64 1229801703532086340, i64 3) nounwind
+ ret i32 0
+}
; D, in little endian the source reg will be 4 bytes into the long long
-;LITTLE: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
-;LITTLE: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
-;LITTLE-NEXT: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
-;LITTLE: #APP
-;LITTLE: or ${{[0-9]+}},$[[FIRST]],${{[0-9]+}}
-;LITTLE: #NO_APP
+define i32 @constraint_D() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_D:
+;CHECK_LITTLE_32: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
+;CHECK_LITTLE_32: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
+;CHECK_LITTLE_32: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
+;CHECK_LITTLE_32: #NO_APP
; D, in big endian the source reg will also be 4 bytes into the long long
-;BIG: #APP
-;BIG: #APP
-;BIG: #APP
-;BIG: #APP
-;BIG: #APP
-;BIG: #APP
-;BIG: #APP
-;BIG: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
-;BIG: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
-;BIG-NEXT: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
-;BIG: #APP
-;BIG: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
-;BIG: #NO_APP
- %7 = load i64* getelementptr inbounds (%union.u_tag* @uval, i32 0, i32 0), align 8
- %trunc1 = trunc i64 %7 to i32
- tail call i32 asm sideeffect "or $0,${1:D},$2", "=r,r,r"(i64 %7, i32 %trunc1) nounwind
-
-; L, in little endian the source reg will be 4 bytes into the long long
-;LITTLE: #APP
-;LITTLE: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
-;LITTLE: #NO_APP
-; L, in big endian the source reg will be 0 bytes into the long long
-;BIG: #APP
-;BIG: or ${{[0-9]+}},$[[FIRST]],${{[0-9]+}}
-;BIG: #NO_APP
- tail call i32 asm sideeffect "or $0,${1:L},$2", "=r,r,r"(i64 %7, i32 %trunc1) nounwind
+;CHECK_BIG_32: constraint_D:
+;CHECK_BIG_32: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
+;CHECK_BIG_32: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
+;CHECK_BIG_32: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
+;CHECK_BIG_32: #APP
+;CHECK_BIG_32: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
+;CHECK_BIG_32: #NO_APP
+ %bosco = load i64* getelementptr inbounds (%union.u_tag* @uval, i32 0, i32 0), align 8
+ %trunc1 = trunc i64 %bosco to i32
+ tail call i32 asm sideeffect "or $0,${1:D},$2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind
+ ret i32 0
+}
+; L, in little endian the source reg will be 0 bytes into the long long
+define i32 @constraint_L() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_L:
+;CHECK_LITTLE_32: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
+;CHECK_LITTLE_32: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
+;CHECK_LITTLE_32: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: or ${{[0-9]+}},$[[FIRST]],${{[0-9]+}}
+;CHECK_LITTLE_32: #NO_APP
+; L, in big endian the source reg will be 4 bytes into the long long
+;CHECK_BIG_32: constraint_L:
+;CHECK_BIG_32: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
+;CHECK_BIG_32: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
+;CHECK_BIG_32: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
+;CHECK_BIG_32: #APP
+;CHECK_BIG_32: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
+;CHECK_BIG_32: #NO_APP
+ %bosco = load i64* getelementptr inbounds (%union.u_tag* @uval, i32 0, i32 0), align 8
+ %trunc1 = trunc i64 %bosco to i32
+ tail call i32 asm sideeffect "or $0,${1:L},$2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind
ret i32 0
}
+; M, in little endian the source reg will be 4 bytes into the long long
+define i32 @constraint_M() nounwind {
+entry:
+;CHECK_LITTLE_32: constraint_M:
+;CHECK_LITTLE_32: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
+;CHECK_LITTLE_32: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
+;CHECK_LITTLE_32: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
+;CHECK_LITTLE_32: #APP
+;CHECK_LITTLE_32: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
+;CHECK_LITTLE_32: #NO_APP
+; M, in big endian the source reg will be 0 bytes into the long long
+;CHECK_BIG_32: constraint_M:
+;CHECK_BIG_32: lw ${{[0-9]+}}, %got(uval)(${{[0-9,a-z]+}})
+;CHECK_BIG_32: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
+;CHECK_BIG_32: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
+;CHECK_BIG_32: #APP
+;CHECK_BIG_32: or ${{[0-9]+}},$[[FIRST]],${{[0-9]+}}
+;CHECK_BIG_32: #NO_APP
+ %bosco = load i64* getelementptr inbounds (%union.u_tag* @uval, i32 0, i32 0), align 8
+ %trunc1 = trunc i64 %bosco to i32
+ tail call i32 asm sideeffect "or $0,${1:M},$2", "=r,r,r"(i64 %bosco, i32 %trunc1) nounwind
+ ret i32 0
+}