[llvm] r215315 - @l and friends adjust their value depending the context used in.

Joerg Sonnenberger joerg at bec.de
Sun Aug 10 05:41:50 PDT 2014


Author: joerg
Date: Sun Aug 10 07:41:50 2014
New Revision: 215315

URL: http://llvm.org/viewvc/llvm-project?rev=215315&view=rev
Log:
@l and friends adjust their value depending the context used in.
For ori, they are unsigned, for addi, signed. Create a new target
expression type to handle this and evaluate Fixups accordingly.

Modified:
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
    llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s
    llvm/trunk/test/MC/PowerPC/ppc64-fixups.s

Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=215315&r1=215314&r2=215315&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Sun Aug 10 07:41:50 2014
@@ -297,6 +297,7 @@ struct PPCOperand : public MCParsedAsmOp
   enum KindTy {
     Token,
     Immediate,
+    ContextImmediate,
     Expression,
     TLSRegister
   } Kind;
@@ -341,6 +342,7 @@ public:
       Tok = o.Tok;
       break;
     case Immediate:
+    case ContextImmediate:
       Imm = o.Imm;
       break;
     case Expression:
@@ -365,6 +367,16 @@ public:
     assert(Kind == Immediate && "Invalid access!");
     return Imm.Val;
   }
+  int64_t getImmS16Context() const {
+    assert((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!");
+    if (Kind == Immediate)
+      return Imm.Val;
+    return static_cast<int16_t>(Imm.Val);
+  }
+  int64_t getImmU16Context() const {
+    assert((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!");
+    return Imm.Val;
+  }
 
   const MCExpr *getExpr() const {
     assert(Kind == Expression && "Invalid access!");
@@ -422,15 +434,42 @@ public:
   bool isU8ImmX8() const { return Kind == Immediate &&
                                   isUInt<8>(getImm()) &&
                                   (getImm() & 7) == 0; }
-  bool isU16Imm() const { return Kind == Expression ||
-                                 (Kind == Immediate && isUInt<16>(getImm())); }
-  bool isS16Imm() const { return Kind == Expression ||
-                                 (Kind == Immediate && isInt<16>(getImm())); }
+  bool isU16Imm() const {
+    switch (Kind) {
+      case Expression:
+        return true;
+      case Immediate:
+      case ContextImmediate:
+        return isUInt<16>(getImmU16Context());
+      default:
+        return false;
+    }
+  }
+  bool isS16Imm() const {
+    switch (Kind) {
+      case Expression:
+        return true;
+      case Immediate:
+      case ContextImmediate:
+        return isInt<16>(getImmS16Context());
+      default:
+        return false;
+    }
+  }
   bool isS16ImmX4() const { return Kind == Expression ||
                                    (Kind == Immediate && isInt<16>(getImm()) &&
                                     (getImm() & 3) == 0); }
-  bool isS17Imm() const { return Kind == Expression ||
-                                 (Kind == Immediate && isInt<17>(getImm())); }
+  bool isS17Imm() const {
+    switch (Kind) {
+      case Expression:
+        return true;
+      case Immediate:
+      case ContextImmediate:
+        return isInt<17>(getImmS16Context());
+      default:
+        return false;
+    }
+  }
   bool isTLSReg() const { return Kind == TLSRegister; }
   bool isDirectBr() const {
     if (Kind == Expression)
@@ -553,6 +592,36 @@ public:
       Inst.addOperand(MCOperand::CreateExpr(getExpr()));
   }
 
+  void addS16ImmOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    switch (Kind) {
+      case Immediate:
+        Inst.addOperand(MCOperand::CreateImm(getImm()));
+        break;
+      case ContextImmediate:
+        Inst.addOperand(MCOperand::CreateImm(getImmS16Context()));
+        break;
+      default:
+        Inst.addOperand(MCOperand::CreateExpr(getExpr()));
+        break;
+    }
+  }
+
+  void addU16ImmOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    switch (Kind) {
+      case Immediate:
+        Inst.addOperand(MCOperand::CreateImm(getImm()));
+        break;
+      case ContextImmediate:
+        Inst.addOperand(MCOperand::CreateImm(getImmU16Context()));
+        break;
+      default:
+        Inst.addOperand(MCOperand::CreateExpr(getExpr()));
+        break;
+    }
+  }
+
   void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     if (Kind == Immediate)
@@ -634,6 +703,16 @@ public:
   }
 
   static std::unique_ptr<PPCOperand>
+  CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
+    auto Op = make_unique<PPCOperand>(ContextImmediate);
+    Op->Imm.Val = Val;
+    Op->StartLoc = S;
+    Op->EndLoc = E;
+    Op->IsPPC64 = IsPPC64;
+    return Op;
+  }
+
+  static std::unique_ptr<PPCOperand>
   CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
       return CreateImm(CE->getValue(), S, E, IsPPC64);
@@ -642,6 +721,12 @@ public:
       if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS)
         return CreateTLSReg(SRE, S, E, IsPPC64);
 
+    if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
+      int64_t Res;
+      if (TE->EvaluateAsConstant(Res))
+        return CreateContextImm(Res, S, E, IsPPC64);
+    }
+
     return CreateExpr(Val, S, E, IsPPC64);
   }
 };
@@ -654,6 +739,7 @@ void PPCOperand::print(raw_ostream &OS)
     OS << "'" << getToken() << "'";
     break;
   case Immediate:
+  case ContextImmediate:
     OS << getImm();
     break;
   case Expression:

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp?rev=215315&r1=215314&r2=215315&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp Sun Aug 10 07:41:50 2014
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "PPCFixupKinds.h"
 #include "PPCMCExpr.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCAssembler.h"
@@ -52,6 +53,43 @@ void PPCMCExpr::PrintImpl(raw_ostream &O
 }
 
 bool
+PPCMCExpr::EvaluateAsConstant(int64_t &Res) const {
+  MCValue Value;
+
+  if (!getSubExpr()->EvaluateAsRelocatable(Value, nullptr, nullptr))
+    return false;
+
+  if (!Value.isAbsolute())
+    return false;
+
+  Res = EvaluateAsInt64(Value.getConstant());
+  return true;
+}
+
+int64_t
+PPCMCExpr::EvaluateAsInt64(int64_t Value) const {
+  switch (Kind) {
+    case VK_PPC_LO:
+      return Value & 0xffff;
+    case VK_PPC_HI:
+      return (Value >> 16) & 0xffff;
+    case VK_PPC_HA:
+      return ((Value + 0x8000) >> 16) & 0xffff;
+    case VK_PPC_HIGHER:
+      return (Value >> 32) & 0xffff;
+    case VK_PPC_HIGHERA:
+      return ((Value + 0x8000) >> 32) & 0xffff;
+    case VK_PPC_HIGHEST:
+      return (Value >> 48) & 0xffff;
+    case VK_PPC_HIGHESTA:
+      return ((Value + 0x8000) >> 48) & 0xffff;
+    case VK_PPC_None:
+      break;
+  }
+  llvm_unreachable("Invalid kind!");
+}
+
+bool
 PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
                                      const MCAsmLayout *Layout,
                                      const MCFixup *Fixup) const {
@@ -61,32 +99,10 @@ PPCMCExpr::EvaluateAsRelocatableImpl(MCV
     return false;
 
   if (Value.isAbsolute()) {
-    int64_t Result = Value.getConstant();
-    switch (Kind) {
-      default:
-        llvm_unreachable("Invalid kind!");
-      case VK_PPC_LO:
-        Result = Result & 0xffff;
-        break;
-      case VK_PPC_HI:
-        Result = (Result >> 16) & 0xffff;
-        break;
-      case VK_PPC_HA:
-        Result = ((Result + 0x8000) >> 16) & 0xffff;
-        break;
-      case VK_PPC_HIGHER:
-        Result = (Result >> 32) & 0xffff;
-        break;
-      case VK_PPC_HIGHERA:
-        Result = ((Result + 0x8000) >> 32) & 0xffff;
-        break;
-      case VK_PPC_HIGHEST:
-        Result = (Result >> 48) & 0xffff;
-        break;
-      case VK_PPC_HIGHESTA:
-        Result = ((Result + 0x8000) >> 48) & 0xffff;
-        break;
-    }
+    int64_t Result = EvaluateAsInt64(Value.getConstant());
+    if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
+        (Result >= 0x8000))
+      return false;
     Res = MCValue::get(Result);
   } else {
     if (!Layout)

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h?rev=215315&r1=215314&r2=215315&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h Sun Aug 10 07:41:50 2014
@@ -34,6 +34,8 @@ private:
   const MCExpr *Expr;
   bool IsDarwin;
 
+  int64_t EvaluateAsInt64(int64_t Value) const;
+
   explicit PPCMCExpr(VariantKind _Kind, const MCExpr *_Expr,
                      bool _IsDarwin)
     : Kind(_Kind), Expr(_Expr), IsDarwin(_IsDarwin) {}
@@ -88,6 +90,8 @@ public:
   // There are no TLS PPCMCExprs at the moment.
   void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
 
+  bool EvaluateAsConstant(int64_t &Res) const;
+
   static bool classof(const MCExpr *E) {
     return E->getKind() == MCExpr::Target;
   }

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=215315&r1=215314&r2=215315&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Sun Aug 10 07:41:50 2014
@@ -458,7 +458,7 @@ def u6imm   : Operand<i32> {
 }
 def PPCS16ImmAsmOperand : AsmOperandClass {
   let Name = "S16Imm"; let PredicateMethod = "isS16Imm";
-  let RenderMethod = "addImmOperands";
+  let RenderMethod = "addS16ImmOperands";
 }
 def s16imm  : Operand<i32> {
   let PrintMethod = "printS16ImmOperand";
@@ -468,7 +468,7 @@ def s16imm  : Operand<i32> {
 }
 def PPCU16ImmAsmOperand : AsmOperandClass {
   let Name = "U16Imm"; let PredicateMethod = "isU16Imm";
-  let RenderMethod = "addImmOperands";
+  let RenderMethod = "addU16ImmOperands";
 }
 def u16imm  : Operand<i32> {
   let PrintMethod = "printU16ImmOperand";
@@ -478,7 +478,7 @@ def u16imm  : Operand<i32> {
 }
 def PPCS17ImmAsmOperand : AsmOperandClass {
   let Name = "S17Imm"; let PredicateMethod = "isS17Imm";
-  let RenderMethod = "addImmOperands";
+  let RenderMethod = "addS16ImmOperands";
 }
 def s17imm  : Operand<i32> {
   // This operand type is used for addis/lis to allow the assembler parser
@@ -554,7 +554,7 @@ def ptr_rc_idx : Operand<iPTR>, PointerL
 
 def PPCDispRIOperand : AsmOperandClass {
  let Name = "DispRI"; let PredicateMethod = "isS16Imm";
- let RenderMethod = "addImmOperands";
+ let RenderMethod = "addS16ImmOperands";
 }
 def dispRI : Operand<iPTR> {
   let ParserMatchClass = PPCDispRIOperand;

Modified: llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s?rev=215315&r1=215314&r2=215315&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-fixup-apply.s Sun Aug 10 07:41:50 2014
@@ -27,6 +27,8 @@ subis 1, 1, target4-target3 at ha
 
 addi 1, 1, target5+0x8000 at l
 addis 1, 1, target5+0x8000 at ha
+ori 1, 1, target5+0x8000 at l
+oris 1, 1, target5+0x8000 at ha
 
 .set target5, 0x10000001
 
@@ -68,7 +70,7 @@ addis 1, 1, target7 at highesta
 # CHECK-NEXT:    ]
 # CHECK-NEXT:    Address: 0x0
 # CHECK-NEXT:    Offset:
-# CHECK-NEXT:    Size: 64
+# CHECK-NEXT:    Size: 72
 # CHECK-NEXT:    Link: 0
 # CHECK-NEXT:    Info: 0
 # CHECK-NEXT:    AddressAlignment: 4
@@ -78,10 +80,12 @@ addis 1, 1, target7 at highesta
 # CHECK-LE-NEXT:   0000: 34122138 3412213C 78562138 3412213C
 # CHECK-BE-NEXT:   0010: 38214444 3C211111 38218001 3C211001
 # CHECK-LE-NEXT:   0010: 44442138 1111213C 01802138 0110213C
-# CHECK-BE-NEXT:   0020: 38210008 3C210000 38214321 3C214321
-# CHECK-LE-NEXT:   0020: 08002138 0000213C 21432138 2143213C
-# CHECK-BE-NEXT:   0030: 3821FFFF 3C211234 38210000 3C211235
-# CHECK-LE-NEXT:   0030: FFFF2138 3412213C 00002138 3512213C
+# CHECK-BE-NEXT:   0020: 60218001 64211001 38210008 3C210000
+# CHECK-LE-NEXT:   0020: 01802160 01102164 08002138 0000213C
+# CHECK-BE-NEXT:   0030: 38214321 3C214321 3821FFFF 3C211234
+# CHECK-LE-NEXT:   0030: 21432138 2143213C FFFF2138 3412213C
+# CHECK-BE-NEXT:   0040: 38210000 3C211235
+# CHECK-LE-NEXT:   0040: 00002138 3512213C
 # CHECK-NEXT:    )
 # CHECK-NEXT:  }
 

Modified: llvm/trunk/test/MC/PowerPC/ppc64-fixups.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-fixups.s?rev=215315&r1=215314&r2=215315&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-fixups.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-fixups.s Sun Aug 10 07:41:50 2014
@@ -687,6 +687,18 @@ base:
 # CHECK-BE: ori 1, 2, 2                  # encoding: [0x60,0x41,0x00,0x02]
 # CHECK-LE: ori 1, 2, 2                  # encoding: [0x02,0x00,0x41,0x60]
             ori 1, 2, 131071 at ha
+# CHECK-BE: addi 1, 2, -1                # encoding: [0x38,0x22,0xff,0xff]
+# CHECK-LE: addi 1, 2, -1                # encoding: [0xff,0xff,0x22,0x38]
+            addi 1, 2, 131071 at l
+# CHECK-BE: addi 1, 2, 1                 # encoding: [0x38,0x22,0x00,0x01]
+# CHECK-LE: addi 1, 2, 1                 # encoding: [0x01,0x00,0x22,0x38]
+            addi 1, 2, 131071 at h
+# CHECK-BE: addi 1, 2, 2                 # encoding: [0x38,0x22,0x00,0x02]
+# CHECK-LE: addi 1, 2, 2                 # encoding: [0x02,0x00,0x22,0x38]
+            addi 1, 2, 131071 at ha
+# CHECK-BE: addis 1, 2, -4096            # encoding: [0x3c,0x22,0xf0,0x00]
+# CHECK-LE: addis 1, 2, -4096            # encoding: [0x00,0xf0,0x22,0x3c]
+            addis 1, 2, 0xf0000000 at h
 
 # Data relocs
 # llvm-mc does not show any "encoding" string for data, so we just check the relocs





More information about the llvm-commits mailing list