[LLVMdev] [cfe-dev] [MIPS] How can I add a constraint to LLVM/Clang for MIPS BE?

Jia Liu proljc at gmail.com
Thu Feb 28 08:12:23 PST 2013


Hi all,

I find clang-mips doesn't support constraint 'R' and I'm trying make
LLVM/Clang support it.
I did a little job, but Clang can not generate right code, it use the
same register in inline asm,
and the binary will segment fault in MIPS environment.

My test case:
/* constraint.c */
#include <stdio.h>

int main(int argc, char* argv[])
{
    int a = 4;
    int b = 10;
    int c = 0xffbbccdd;

    int *p = &a;
    int out = 0;

    __asm volatile (
        "lw %0, %1\n\t"
        : "=r"(out)
        : "R"(*p)
        );
    printf("out is %d\n", out);

    p = &b;
    __asm volatile (
        "lw %0, %1\n\t"
        : "=r"(out)
        : "R"(*p)
        );
    printf("out is %d\n", out);

    p = &c;
    __asm volatile (
        "lwl %0, 1 + %1\n\t"
        "lwr %0, 2 + %1\n\t"
        : "=r"(out)
        : "R"(*p)
        );
    printf("out is %x\n", out);

    return 0;
}

LLVM-MIPS-BE diff:
diff --git a/lib/Target/Mips/MipsISelLowering.cpp
b/lib/Target/Mips/MipsISelLowering.cpp
index 36e1a15..4a5d045 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -3880,6 +3880,8 @@ getConstraintType(const std::string &Constraint) const
       case 'l':
       case 'x':
         return C_RegisterClass;
+      case 'R':
+        return C_Memory;
     }
   }
   return TargetLowering::getConstraintType(Constraint);
@@ -3928,6 +3930,9 @@ MipsTargetLowering::getSingleConstraintMatchWeight(
     if (isa<ConstantInt>(CallOperandVal))
       weight = CW_Constant;
     break;
+  case 'R': // An address that can be used in a non-macro load or store
+    weight = CW_Memory;
+    break;
   }
   return weight;
 }

Clang-diff:
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 70ea235..26fc663 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -462,6 +462,7 @@ bool
TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
     case 'N':
     case 'O':
     case 'P':
+    case 'R':
       break;
     case 'r': // general register.
       Info.setAllowsRegister();
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 24a69ee..854e12b 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -4393,6 +4393,9 @@ public:
     case 'x': // hilo register pair
       Info.setAllowsRegister();
       return true;
+    case 'R': // An address that can be used in a non-macro load or store
+      Info.setAllowsMemory();
+      return true;
     }
   }

Clang gen asm frag:
	#APP
	lw $2, 0($2)
	#NO_APP

	#APP
	lw $1, 0($1)
	#NO_APP

	#APP
	lwl $1, 1 + 0($1)
	lwr $1, 2 + 0($1)
	#NO_APP

gcc gen asm frag:
#APP
 # 12 "constraints.c" 1
	lw $16, 0($2)
 # 0 "" 2
#NO_APP

#APP
 # 20 "constraints.c" 1
	lw $16, 0($2)
 # 0 "" 2
#NO_APP

#APP
 # 28 "constraints.c" 1
	lwl $16, 1 + 0($2)
	lwr $16, 2 + 0($2)
 # 0 "" 2
#NO_APP

Clang use the same register in inline asm, gcc use different ones, and
gcc way is right, the clang generated code will segment fault on MIPS
environment.
Am I missed something or made something wrong?

Regards,
Jia
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang-mips-constraints.diff
Type: application/octet-stream
Size: 801 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130301/f7b00dce/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: constraints.c
Type: text/x-csrc
Size: 601 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130301/f7b00dce/attachment.c>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: constraints.clang.s
Type: application/octet-stream
Size: 1728 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130301/f7b00dce/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: constraints.gcc.s
Type: application/octet-stream
Size: 1684 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130301/f7b00dce/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: llvm-mips-constraints.diff
Type: application/octet-stream
Size: 755 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130301/f7b00dce/attachment-0003.obj>


More information about the llvm-dev mailing list