[llvm-commits] [PATCH 11/11] (patch) Mips specific inline asm: constraint 'l'
Jack Carter
jcarter at mips.com
Thu Apr 12 13:52:20 PDT 2012
The lo register. Use this register to store values that are no bigger than a word.
An example of this is:
main()
{
int i_input_1 = 7;int i_input_2 = 6;int i_result = 0;int i_temp = 44;
__asm__ __volatile__(
".set noreorder \n\t\t"
"mtlo %3 \n\t\t"
"madd %1,%2 \n\t\t"
".set reorder \n\t\t"
: "=l" (i_result)
: "r" (i_input_1), "r" (i_input_2), "r" (i_temp));
printf ("mips_madd(%d,%d) = %d\n", i_input_1, i_input_2, i_result);
printf ("i_temp = %d\n", i_temp);
}
In the output disassembly there will be a mflo instruction just
outside of the inlined code moving the result from the lo register
to a GPR so it can be printed.
---
lib/Target/Mips/MipsISelLowering.cpp | 7 +++++++
test/CodeGen/Mips/inlineasm-cnstrnt-bad-l.ll | 14 ++++++++++++++
test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll | 11 +++++++++++
3 files changed, 32 insertions(+), 0 deletions(-)
create mode 100644 test/CodeGen/Mips/inlineasm-cnstrnt-bad-l.ll
-------------- next part --------------
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index cac819e..e54bd63 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -2888,6 +2888,7 @@ getConstraintType(const std::string &Constraint) const
// backwards compatibility.
// 'c' : A register suitable for use in an indirect
// jump. This will always be $25 for -mabicalls.
+ // 'l' : The lo register.
if (Constraint.size() == 1) {
switch (Constraint[0]) {
default : break;
@@ -2895,6 +2896,7 @@ getConstraintType(const std::string &Constraint) const
case 'y':
case 'f':
case 'c':
+ case 'l':
return C_RegisterClass;
}
}
@@ -2929,6 +2931,7 @@ MipsTargetLowering::getSingleConstraintMatchWeight(
weight = CW_Register;
break;
case 'c': // $25 for indirect jumps
+ case 'l': // lo register
if (type->isIntegerTy())
weight = CW_SpecificReg;
break;
@@ -2978,6 +2981,10 @@ getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
return std::make_pair((unsigned)Mips::T9, Mips::CPURegsRegisterClass);
assert(VT == MVT::i64 && "Unexpected type.");
return std::make_pair((unsigned)Mips::T9_64, Mips::CPU64RegsRegisterClass);
+ case 'l': // register suitable for indirect jump
+ if (VT == MVT::i32)
+ return std::make_pair((unsigned)Mips::LO, Mips::HILORegisterClass);
+ return std::make_pair((unsigned)Mips::LO64, Mips::HILO64RegisterClass);
}
}
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
diff --git a/test/CodeGen/Mips/inlineasm-cnstrnt-bad-l.ll b/test/CodeGen/Mips/inlineasm-cnstrnt-bad-l.ll
new file mode 100644
index 0000000..9bd4b26
--- /dev/null
+++ b/test/CodeGen/Mips/inlineasm-cnstrnt-bad-l.ll
@@ -0,0 +1,14 @@
+;XFAIL:
+;
+;This is a negative test.
+; Register consraint 'l' specifies the "lo" register which
+; gets values, but is not accessable by name. Here we try
+; to use it directly in the instruction operand.
+;
+; RUN: not llc -march=mipsel < %s
+
+define i32 @main() nounwind {
+entry:
+ tail call i16 asm sideeffect "addi $0,$1,$2", "=l,r,I"(i16 7, i16 3) nounwind
+ ret i32 0
+}
diff --git a/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll b/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll
index e6fe14c..47eccf6 100644
--- a/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll
+++ b/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll
@@ -29,5 +29,16 @@ entry:
; CHECK: #NO_APP
tail call i32 asm sideeffect "addi $0,$1,$2", "=c,c,I"(i32 4194304, i32 1024) nounwind
+; Now l with 1024: make sure register lo is picked. We do this by checking the instruction
+; after the inline expression for a mflo to pull the value out of lo.
+; CHECK: #APP
+; CHECK-NEXT: mtlo ${{[0-9]+}}
+; CHECK-NEXT: madd ${{[0-9]+}},${{[0-9]+}}
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: mflo ${{[0-9]+}}
+ %bosco = alloca i32, align 4
+ call i32 asm sideeffect "\09mtlo $3 \0A\09\09madd $1,$2 ", "=l,r,r,r"(i32 7, i32 6, i32 44) nounwind
+ store volatile i32 %3, i32* %bosco, align 4
+
ret i32 0
}
More information about the llvm-commits
mailing list