[llvm-commits] [llvm] r160429 - in /llvm/trunk: lib/Target/Mips/MipsAsmPrinter.cpp test/CodeGen/Mips/inlineasm-operand-code.ll

Jack Carter jcarter at mips.com
Tue Jul 17 23:41:36 PDT 2012


Author: jacksprat
Date: Wed Jul 18 01:41:36 2012
New Revision: 160429

URL: http://llvm.org/viewvc/llvm-project?rev=160429&view=rev
Log:
Mips specific inline asm operand modifier 'M':

Print the high order register of a double word register operand.

In 32 bit mode, a 64 bit double word integer will be represented
by 2 32 bit registers. This modifier causes the high order register
to be used in the asm expression. It is useful if you are using 
doubles in assembler and continue to control register to variable
relationships.

This patch also fixes a related bug in a previous patch:

    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

I got 'D' and 'M' confused. The second part of a double word operand
will only match 'M' for one of the endianesses. I had 'L' and 'D'
be the opposite twins when 'L' and 'M' are.

Modified:
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
    llvm/trunk/test/CodeGen/Mips/inlineasm-operand-code.ll

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=160429&r1=160428&r2=160429&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Wed Jul 18 01:41:36 2012
@@ -355,6 +355,7 @@
     }
     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 @@
       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;

Modified: llvm/trunk/test/CodeGen/Mips/inlineasm-operand-code.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/inlineasm-operand-code.ll?rev=160429&r1=160428&r2=160429&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/inlineasm-operand-code.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/inlineasm-operand-code.ll Wed Jul 18 01:41:36 2012
@@ -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
+}





More information about the llvm-commits mailing list