Index: lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp =================================================================== --- lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -124,59 +124,124 @@ static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, raw_ostream &OS) { - int Offset = 0; const MCSymbolRefExpr *SRE; + const MCBinaryExpr *BE; - if (const MCBinaryExpr *BE = dyn_cast(Expr)) { + int64_t Absolute; + if (Expr->evaluateAsAbsolute(Absolute)) { + OS << Absolute; + return; + } + + if ((BE = dyn_cast(Expr))) { SRE = dyn_cast(BE->getLHS()); - const MCConstantExpr *CE = dyn_cast(BE->getRHS()); - assert(SRE && CE && "Binary expression must be sym+const."); - Offset = CE->getValue(); + if (!SRE) + printExpr(BE->getLHS(), MAI, OS); + } else if (const MCUnaryExpr *UE = dyn_cast(Expr)) { + switch (UE->getOpcode()) { + default: + llvm_unreachable("Invalid unary opcode"); + case MCUnaryExpr::Opcode::Minus: + OS << '-'; + break; + case MCUnaryExpr::Opcode::Not: + OS << '~'; + break; + case MCUnaryExpr::Opcode::Plus: + OS << '+'; + break; + case MCUnaryExpr::Opcode::LNot: + llvm_unreachable("Unsupported unary opcode in this context"); + } + printExpr(UE->getSubExpr(), MAI, OS); + return; } else if (const MipsMCExpr *ME = dyn_cast(Expr)) { ME->print(OS, MAI); return; + } else if ((SRE = cast(Expr))) { + // Symbols will be printed later } else - SRE = cast(Expr); - - MCSymbolRefExpr::VariantKind Kind = SRE->getKind(); - - switch (Kind) { - default: llvm_unreachable("Invalid kind!"); - case MCSymbolRefExpr::VK_None: break; - case MCSymbolRefExpr::VK_Mips_GPREL: OS << "%gp_rel("; break; - case MCSymbolRefExpr::VK_Mips_GOT_CALL: OS << "%call16("; break; - case MCSymbolRefExpr::VK_Mips_GOT16: OS << "%got("; break; - case MCSymbolRefExpr::VK_Mips_GOT: OS << "%got("; break; - case MCSymbolRefExpr::VK_Mips_ABS_HI: OS << "%hi("; break; - case MCSymbolRefExpr::VK_Mips_ABS_LO: OS << "%lo("; break; - case MCSymbolRefExpr::VK_Mips_TLSGD: OS << "%tlsgd("; break; - case MCSymbolRefExpr::VK_Mips_TLSLDM: OS << "%tlsldm("; break; - case MCSymbolRefExpr::VK_Mips_DTPREL_HI: OS << "%dtprel_hi("; break; - case MCSymbolRefExpr::VK_Mips_DTPREL_LO: OS << "%dtprel_lo("; break; - case MCSymbolRefExpr::VK_Mips_GOTTPREL: OS << "%gottprel("; break; - case MCSymbolRefExpr::VK_Mips_TPREL_HI: OS << "%tprel_hi("; break; - case MCSymbolRefExpr::VK_Mips_TPREL_LO: OS << "%tprel_lo("; break; - case MCSymbolRefExpr::VK_Mips_GPOFF_HI: OS << "%hi(%neg(%gp_rel("; break; - case MCSymbolRefExpr::VK_Mips_GPOFF_LO: OS << "%lo(%neg(%gp_rel("; break; - case MCSymbolRefExpr::VK_Mips_GOT_DISP: OS << "%got_disp("; break; - case MCSymbolRefExpr::VK_Mips_GOT_PAGE: OS << "%got_page("; break; - case MCSymbolRefExpr::VK_Mips_GOT_OFST: OS << "%got_ofst("; break; - case MCSymbolRefExpr::VK_Mips_HIGHER: OS << "%higher("; break; - case MCSymbolRefExpr::VK_Mips_HIGHEST: OS << "%highest("; break; - case MCSymbolRefExpr::VK_Mips_GOT_HI16: OS << "%got_hi("; break; - case MCSymbolRefExpr::VK_Mips_GOT_LO16: OS << "%got_lo("; break; - case MCSymbolRefExpr::VK_Mips_CALL_HI16: OS << "%call_hi("; break; - case MCSymbolRefExpr::VK_Mips_CALL_LO16: OS << "%call_lo("; break; - case MCSymbolRefExpr::VK_Mips_PCREL_HI16: OS << "%pcrel_hi("; break; - case MCSymbolRefExpr::VK_Mips_PCREL_LO16: OS << "%pcrel_lo("; break; + llvm_unreachable("Unknown expression type"); + + MCSymbolRefExpr::VariantKind Kind; + if (SRE) { + Kind = SRE->getKind(); + + switch (Kind) { + default: llvm_unreachable("Invalid kind!"); + case MCSymbolRefExpr::VK_None: break; + case MCSymbolRefExpr::VK_Mips_GPREL: OS << "%gp_rel("; break; + case MCSymbolRefExpr::VK_Mips_GOT_CALL: OS << "%call16("; break; + case MCSymbolRefExpr::VK_Mips_GOT16: OS << "%got("; break; + case MCSymbolRefExpr::VK_Mips_GOT: OS << "%got("; break; + case MCSymbolRefExpr::VK_Mips_ABS_HI: OS << "%hi("; break; + case MCSymbolRefExpr::VK_Mips_ABS_LO: OS << "%lo("; break; + case MCSymbolRefExpr::VK_Mips_TLSGD: OS << "%tlsgd("; break; + case MCSymbolRefExpr::VK_Mips_TLSLDM: OS << "%tlsldm("; break; + case MCSymbolRefExpr::VK_Mips_DTPREL_HI: OS << "%dtprel_hi("; break; + case MCSymbolRefExpr::VK_Mips_DTPREL_LO: OS << "%dtprel_lo("; break; + case MCSymbolRefExpr::VK_Mips_GOTTPREL: OS << "%gottprel("; break; + case MCSymbolRefExpr::VK_Mips_TPREL_HI: OS << "%tprel_hi("; break; + case MCSymbolRefExpr::VK_Mips_TPREL_LO: OS << "%tprel_lo("; break; + case MCSymbolRefExpr::VK_Mips_GPOFF_HI: OS << "%hi(%neg(%gp_rel("; break; + case MCSymbolRefExpr::VK_Mips_GPOFF_LO: OS << "%lo(%neg(%gp_rel("; break; + case MCSymbolRefExpr::VK_Mips_GOT_DISP: OS << "%got_disp("; break; + case MCSymbolRefExpr::VK_Mips_GOT_PAGE: OS << "%got_page("; break; + case MCSymbolRefExpr::VK_Mips_GOT_OFST: OS << "%got_ofst("; break; + case MCSymbolRefExpr::VK_Mips_HIGHER: OS << "%higher("; break; + case MCSymbolRefExpr::VK_Mips_HIGHEST: OS << "%highest("; break; + case MCSymbolRefExpr::VK_Mips_GOT_HI16: OS << "%got_hi("; break; + case MCSymbolRefExpr::VK_Mips_GOT_LO16: OS << "%got_lo("; break; + case MCSymbolRefExpr::VK_Mips_CALL_HI16: OS << "%call_hi("; break; + case MCSymbolRefExpr::VK_Mips_CALL_LO16: OS << "%call_lo("; break; + case MCSymbolRefExpr::VK_Mips_PCREL_HI16: OS << "%pcrel_hi("; break; + case MCSymbolRefExpr::VK_Mips_PCREL_LO16: OS << "%pcrel_lo("; break; + } + SRE->getSymbol().print(OS, MAI); } - SRE->getSymbol().print(OS, MAI); - - if (Offset) { - if (Offset > 0) + if (BE) { + switch (BE->getOpcode()) { + default: + llvm_unreachable("Unknown binary opcode"); + case MCBinaryExpr::Opcode::Add: OS << '+'; - OS << Offset; + break; + case MCBinaryExpr::Opcode::Sub: + OS << '-'; + break; + case MCBinaryExpr::Opcode::Div: + OS << '/'; + break; + case MCBinaryExpr::Opcode::Mul: + OS << '*'; + break; + case MCBinaryExpr::Opcode::Mod: + OS << '%'; + break; + case MCBinaryExpr::Opcode::Shl: + OS << "<<"; + break; + case MCBinaryExpr::Opcode::AShr: + OS << ">>"; + break; + case MCBinaryExpr::Opcode::LShr: + OS << ">>>"; + break; + case MCBinaryExpr::Opcode::And: + case MCBinaryExpr::Opcode::EQ: + case MCBinaryExpr::Opcode::GT: + case MCBinaryExpr::Opcode::GTE: + case MCBinaryExpr::Opcode::LAnd: + case MCBinaryExpr::Opcode::LOr: + case MCBinaryExpr::Opcode::LT: + case MCBinaryExpr::Opcode::LTE: + case MCBinaryExpr::Opcode::NE: + case MCBinaryExpr::Opcode::Or: + case MCBinaryExpr::Opcode::Xor: + llvm_unreachable("Unsupported binary opcode in this context"); + } + printExpr(BE->getRHS(), MAI, OS); } if ((Kind == MCSymbolRefExpr::VK_Mips_GPOFF_HI) ||