From 8c2eebe4074ef218b30d94358f6b2e45c079605c Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 31 Aug 2009 08:08:38 +0000 Subject: [PATCH] llvm-mc: Switch MCInst to storing an MCExpr* instead of an MCValue. Also, use MCInst::print instead of custom code in MCAsmPrinter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80575 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCInst.h | 30 ++++++------- lib/MC/MCAsmStreamer.cpp | 26 ++---------- lib/MC/MCInst.cpp | 7 ++-- lib/MC/MCMachOStreamer.cpp | 29 ++++++++++++- lib/Target/X86/AsmParser/X86AsmParser.cpp | 42 ++++++++++--------- .../X86/AsmPrinter/X86ATTAsmPrinter.cpp | 27 ++++++++++-- .../X86/AsmPrinter/X86ATTInstPrinter.cpp | 13 +++--- lib/Target/X86/X86CodeEmitter.cpp | 14 +++---- test/MC/AsmParser/labels.s | 4 +- test/MC/AsmParser/x86_operands.s | 10 ++--- 10 files changed, 116 insertions(+), 86 deletions(-) diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 857d29411e6..7c1cb136d69 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -16,13 +16,13 @@ #ifndef LLVM_MC_MCINST_H #define LLVM_MC_MCINST_H -#include "llvm/MC/MCValue.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" namespace llvm { class raw_ostream; +class MCExpr; /// MCOperand - Instances of this class represent operands of the MCInst class. /// This is a simple discriminated union. @@ -32,14 +32,14 @@ class MCOperand { kRegister, ///< Register operand. kImmediate, ///< Immediate operand. kMBBLabel, ///< Basic block label. - kMCValue ///< Relocatable immediate operand. + kExpr ///< Relocatable immediate operand. }; unsigned char Kind; union { unsigned RegVal; int64_t ImmVal; - MCValue MCValueVal; + const MCExpr *ExprVal; struct { unsigned FunctionNo; unsigned BlockNo; @@ -54,7 +54,7 @@ public: bool isReg() const { return Kind == kRegister; } bool isImm() const { return Kind == kImmediate; } bool isMBBLabel() const { return Kind == kMBBLabel; } - bool isMCValue() const { return Kind == kMCValue; } + bool isExpr() const { return Kind == kExpr; } /// getReg - Returns the register number. unsigned getReg() const { @@ -78,21 +78,21 @@ public: } unsigned getMBBLabelFunction() const { - assert(isMBBLabel() && "Wrong accessor"); + assert(isMBBLabel() && "This is not a machine basic block"); return MBBLabel.FunctionNo; } unsigned getMBBLabelBlock() const { - assert(isMBBLabel() && "Wrong accessor"); + assert(isMBBLabel() && "This is not a machine basic block"); return MBBLabel.BlockNo; } - const MCValue &getMCValue() const { - assert(isMCValue() && "This is not an MCValue"); - return MCValueVal; + const MCExpr *getExpr() const { + assert(isExpr() && "This is not an expression"); + return ExprVal; } - void setMCValue(const MCValue &Val) { - assert(isMCValue() && "This is not an MCValue"); - MCValueVal = Val; + void setExpr(const MCExpr *Val) { + assert(isExpr() && "This is not an expression"); + ExprVal = Val; } static MCOperand CreateReg(unsigned Reg) { @@ -114,10 +114,10 @@ public: Op.MBBLabel.BlockNo = MBB; return Op; } - static MCOperand CreateMCValue(const MCValue &Val) { + static MCOperand CreateExpr(const MCExpr *Val) { MCOperand Op; - Op.Kind = kMCValue; - Op.MCValueVal = Val; + Op.Kind = kExpr; + Op.ExprVal = Val; return Op; } diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index e5899fc8995..d0a2ebbc309 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -10,13 +10,14 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/ADT/SmallString.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" -#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Format.h" @@ -271,18 +272,6 @@ void MCAsmStreamer::EmitValueToOffset(const MCValue &Offset, OS << ".org " << Offset << ", " << (unsigned) Value << '\n'; } -static raw_ostream &operator<<(raw_ostream &OS, const MCOperand &Op) { - if (Op.isReg()) - return OS << "reg:" << Op.getReg(); - if (Op.isImm()) - return OS << "imm:" << Op.getImm(); - if (Op.isMBBLabel()) - return OS << "mbblabel:(" - << Op.getMBBLabelFunction() << ", " << Op.getMBBLabelBlock(); - assert(Op.isMCValue() && "Invalid operand!"); - return OS << "val:" << Op.getMCValue(); -} - void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { assert(CurSection && "Cannot emit contents before setting section!"); @@ -312,15 +301,8 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { // Otherwise fall back to a structural printing for now. Eventually we should // always have access to the target specific printer. - OS << "MCInst(" - << "opcode=" << Inst.getOpcode() << ", " - << "operands=["; - for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { - if (i) - OS << ", "; - OS << Inst.getOperand(i); - } - OS << "])\n"; + Inst.print(OS); + OS << '\n'; } void MCAsmStreamer::Finish() { diff --git a/lib/MC/MCInst.cpp b/lib/MC/MCInst.cpp index 469dc7975e5..ec061463b75 100644 --- a/lib/MC/MCInst.cpp +++ b/lib/MC/MCInst.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCExpr.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -23,9 +24,9 @@ void MCOperand::print(raw_ostream &OS) const { else if (isMBBLabel()) OS << "MBB:(" << getMBBLabelFunction() << "," << getMBBLabelBlock() << ")"; - else if (isMCValue()) { - OS << "Value:("; - getMCValue().print(OS); + else if (isExpr()) { + OS << "Expr:("; + getExpr()->print(OS); OS << ")"; } else OS << "UNDEFINED"; diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 5a7b01b4764..7a94e98dd2a 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -12,6 +12,7 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" @@ -95,6 +96,30 @@ public: return Value; } + const MCExpr *AddValueSymbols(const MCExpr *Value) { + switch (Value->getKind()) { + case MCExpr::Constant: + break; + + case MCExpr::Binary: { + const MCBinaryExpr *BE = cast(Value); + AddValueSymbols(BE->getLHS()); + AddValueSymbols(BE->getRHS()); + break; + } + + case MCExpr::SymbolRef: + getSymbolData(cast(Value)->getSymbol()); + break; + + case MCExpr::Unary: + AddValueSymbols(cast(Value)->getSubExpr()); + break; + } + + return Value; + } + /// @name MCStreamer Interface /// @{ @@ -330,8 +355,8 @@ void MCMachOStreamer::EmitValueToOffset(const MCValue &Offset, void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { // Scan for values. for (unsigned i = 0; i != Inst.getNumOperands(); ++i) - if (Inst.getOperand(i).isMCValue()) - AddValueSymbols(Inst.getOperand(i).getMCValue()); + if (Inst.getOperand(i).isExpr()) + AddValueSymbols(Inst.getOperand(i).getExpr()); if (!Emitter) llvm_unreachable("no code emitter available!"); diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 5232beb9c39..d06350b8058 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -12,8 +12,8 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmLexer.h" #include "llvm/MC/MCAsmParser.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCValue.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetAsmParser.h" @@ -85,12 +85,12 @@ struct X86Operand { } Reg; struct { - MCValue Val; + const MCExpr *Val; } Imm; struct { unsigned SegReg; - MCValue Disp; + const MCExpr *Disp; unsigned BaseReg; unsigned IndexReg; unsigned Scale; @@ -107,12 +107,12 @@ struct X86Operand { return Reg.RegNo; } - const MCValue &getImm() const { + const MCExpr *getImm() const { assert(Kind == Immediate && "Invalid access!"); return Imm.Val; } - const MCValue &getMemDisp() const { + const MCExpr *getMemDisp() const { assert(Kind == Memory && "Invalid access!"); return Mem.Disp; } @@ -143,11 +143,12 @@ struct X86Operand { if (!isImm()) return false; - if (!getImm().isAbsolute()) - return true; + if (const MCConstantExpr *CE = dyn_cast(getImm())) { + int64_t Value = CE->getValue(); + return Value == (int64_t) (int8_t) Value; + } - int64_t Value = getImm().getConstant(); - return Value == (int64_t) (int8_t) Value; + return true; } bool isMem() const { return Kind == Memory; } @@ -161,13 +162,13 @@ struct X86Operand { void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateMCValue(getImm())); + Inst.addOperand(MCOperand::CreateExpr(getImm())); } void addImmSExt8Operands(MCInst &Inst, unsigned N) const { // FIXME: Support user customization of the render method. assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateMCValue(getImm())); + Inst.addOperand(MCOperand::CreateExpr(getImm())); } void addMemOperands(MCInst &Inst, unsigned N) const { @@ -176,7 +177,7 @@ struct X86Operand { Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); Inst.addOperand(MCOperand::CreateImm(getMemScale())); Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); - Inst.addOperand(MCOperand::CreateMCValue(getMemDisp())); + Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); // FIXME: What a hack. if (N == 5) @@ -198,15 +199,16 @@ struct X86Operand { return Res; } - static X86Operand CreateImm(MCValue Val) { + static X86Operand CreateImm(const MCExpr *Val) { X86Operand Res; Res.Kind = Immediate; Res.Imm.Val = Val; return Res; } - static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg, - unsigned IndexReg, unsigned Scale) { + static X86Operand CreateMem(unsigned SegReg, const MCExpr *Disp, + unsigned BaseReg, unsigned IndexReg, + unsigned Scale) { // We should never just have a displacement, that would be an immediate. assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); @@ -257,8 +259,8 @@ bool X86ATTAsmParser::ParseOperand(X86Operand &Op) { case AsmToken::Dollar: { // $42 -> immediate. getLexer().Lex(); - MCValue Val; - if (getParser().ParseRelocatableExpression(Val)) + const MCExpr *Val; + if (getParser().ParseExpression(Val)) return true; Op = X86Operand::CreateImm(Val); return false; @@ -275,9 +277,9 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The // only way to do this without lookahead is to eat the ( and see what is after // it. - MCValue Disp = MCValue::get(0, 0, 0); + const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); if (getLexer().isNot(AsmToken::LParen)) { - if (getParser().ParseRelocatableExpression(Disp)) return true; + if (getParser().ParseExpression(Disp)) return true; // After parsing the base expression we could either have a parenthesized // memory address or not. If not, return now. If so, eat the (. @@ -302,7 +304,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { // memory operand consumed. } else { // It must be an parenthesized expression, parse it now. - if (getParser().ParseParenRelocatableExpression(Disp)) + if (getParser().ParseParenExpression(Disp)) return true; // After parsing the base expression we could either have a parenthesized diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index e1b6263a7ad..2058d7d0a05 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Assembly/Writer.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" @@ -794,8 +795,17 @@ MCOperand X86ATTAsmPrinter::LowerGlobalAddressOperand(const MachineOperand &MO){ // Create a symbol for the name. MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name); - return MCOperand::CreateMCValue(MCValue::get(Sym, NegatedSymbol, - MO.getOffset())); + // FIXME: We would like an efficient form for this, so we don't have to do a + // lot of extra uniquing. + const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, OutContext); + if (NegatedSymbol) + Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(NegatedSymbol, + OutContext), + OutContext); + Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), + OutContext), + OutContext); + return MCOperand::CreateExpr(Expr); } MCOperand X86ATTAsmPrinter:: @@ -807,7 +817,13 @@ LowerExternalSymbolOperand(const MachineOperand &MO){ } MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name); - return MCOperand::CreateMCValue(MCValue::get(Sym, 0, MO.getOffset())); + // FIXME: We would like an efficient form for this, so we don't have to do a + // lot of extra uniquing. + const MCExpr *Expr = + MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, OutContext), + MCConstantExpr::Create(MO.getOffset(),OutContext), + OutContext); + return MCOperand::CreateExpr(Expr); } @@ -848,7 +864,10 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { // Emit the call. MCSymbol *PICBase = GetPICBaseSymbol(); TmpInst.setOpcode(X86::CALLpcrel32); - TmpInst.addOperand(MCOperand::CreateMCValue(MCValue::get(PICBase))); + // FIXME: We would like an efficient form for this, so we don't have to do a + // lot of extra uniquing. + TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase, + OutContext))); printInstruction(&TmpInst); // Emit the label. diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp index f45df0c8860..ee797915f78 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCInst.h" #include "X86ATTAsmPrinter.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; @@ -55,8 +56,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) { if (Op.isImm()) O << Op.getImm(); - else if (Op.isMCValue()) - Op.getMCValue().print(O); + else if (Op.isExpr()) + Op.getExpr()->print(O); else if (Op.isMBBLabel()) // FIXME: Keep in sync with printBasicBlockLabel. printBasicBlockLabel // should eventually call into this code, not the other way around. @@ -90,9 +91,9 @@ void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo, O << '$'; O << Op.getImm(); return; - } else if (Op.isMCValue()) { + } else if (Op.isExpr()) { O << '$'; - Op.getMCValue().print(O); + Op.getExpr()->print(O); return; } @@ -109,8 +110,8 @@ void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) { int64_t DispVal = DispSpec.getImm(); if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) O << DispVal; - } else if (DispSpec.isMCValue()) { - DispSpec.getMCValue().print(O); + } else if (DispSpec.isExpr()) { + DispSpec.getExpr()->print(O); } else { llvm_unreachable("non-immediate displacement for LEA?"); //assert(DispSpec.isGlobal() || DispSpec.isCPI() || diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 0c472a725bc..7e2fd975c1c 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -30,6 +30,7 @@ #include "llvm/Function.h" #include "llvm/ADT/Statistic.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -968,12 +969,12 @@ public: Instr->addOperand(MachineOperand::CreateImm(Op.getImm())); return true; } - if (!Op.isMCValue()) + if (!Op.isExpr()) return false; - const MCValue &Val = Op.getMCValue(); - if (Val.isAbsolute()) { - Instr->addOperand(MachineOperand::CreateImm(Val.getConstant())); + const MCExpr *Expr = Op.getExpr(); + if (const MCConstantExpr *CE = dyn_cast(Expr)) { + Instr->addOperand(MachineOperand::CreateImm(CE->getValue())); return true; } @@ -1036,9 +1037,8 @@ public: if (CurOp < NumOps) { // Hack to make branches work. if (!(Desc.TSFlags & X86II::ImmMask) && - MI.getOperand(0).isMCValue() && - MI.getOperand(0).getMCValue().getSymA() && - !MI.getOperand(0).getMCValue().getSymB()) + MI.getOperand(0).isExpr() && + isa(MI.getOperand(0).getExpr())) Instr->addOperand(MachineOperand::CreateMBB(DummyMBB)); else OK &= AddImmToInstr(MI, Instr, CurOp); diff --git a/test/MC/AsmParser/labels.s b/test/MC/AsmParser/labels.s index 0aabc4b50a4..172ee8d8742 100644 --- a/test/MC/AsmParser/labels.s +++ b/test/MC/AsmParser/labels.s @@ -15,12 +15,12 @@ a: foo: // CHECK: addl $24, "a$b"(%eax) addl $24, "a$b"(%eax) -// CHECK: addl $24, "a$b" + 10(%eax) +// CHECK: addl $24, ("a$b" + 10)(%eax) addl $24, ("a$b" + 10)(%eax) // CHECK: "b$c" = 10 "b$c" = 10 -// CHECK: addl $10, %eax +// CHECK: addl $"b$c", %eax addl "b$c", %eax // CHECK: set "a 0", 11 diff --git a/test/MC/AsmParser/x86_operands.s b/test/MC/AsmParser/x86_operands.s index d6c16808cff..f21cf3472e9 100644 --- a/test/MC/AsmParser/x86_operands.s +++ b/test/MC/AsmParser/x86_operands.s @@ -5,11 +5,11 @@ # Immediates # CHECK: addl $1, %eax addl $1, %eax -# CHECK: addl $3, %eax +# CHECK: addl $(1 + 2), %eax addl $(1+2), %eax # CHECK: addl $a, %eax addl $a, %eax -# CHECK: addl $3, %eax +# CHECK: addl $(1 + 2), %eax addl $1 + 2, %eax # Disambiguation @@ -18,15 +18,15 @@ #addl $1, 4+4 # FIXME: Add back when we can match this. #addl $1, (4+4) -# CHECK: addl $1, 8(%eax) +# CHECK: addl $1, (4 + 4)(%eax) addl $1, 4+4(%eax) -# CHECK: addl $1, 8(%eax) +# CHECK: addl $1, (4 + 4)(%eax) addl $1, (4+4)(%eax) # CHECK: addl $1, 8(%eax) addl $1, 8(%eax) # CHECK: addl $1, 0(%eax) addl $1, (%eax) -# CHECK: addl $1, 8(,%eax) +# CHECK: addl $1, (4 + 4)(,%eax) addl $1, (4+4)(,%eax) # Indirect Memory Operands