diff --git a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp index 37ebff3f163..e1e64d3ac17 100644 --- a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp +++ b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp @@ -124,18 +124,6 @@ void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum, O << *MO.getExpr(); } -void SystemZInstPrinter::printCallOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - const MCOperand &MO = MI->getOperand(OpNum); - if (MO.isImm()) { - O << "0x"; - O.write_hex(MO.getImm()); - } else { - O << *MO.getExpr(); - O << "@PLT"; - } -} - void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum, raw_ostream &O) { printOperand(MI->getOperand(OpNum), O); diff --git a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h index 30cdee56482..734ecf0ff23 100644 --- a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h +++ b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h @@ -58,7 +58,6 @@ private: void printS32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printU32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printPCRelOperand(const MCInst *MI, int OpNum, raw_ostream &O); - void printCallOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printAccessRegOperand(const MCInst *MI, int OpNum, raw_ostream &O); // Print the mnemonic for a condition-code mask ("ne", "lh", etc.) diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp index 11b520da912..26a8faeea10 100644 --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp @@ -35,15 +35,6 @@ static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value) { llvm_unreachable("Unknown fixup kind!"); } -// If Opcode is a relaxable interprocedural reference, return the relaxed form, -// otherwise return 0. -static unsigned getRelaxedOpcode(unsigned Opcode) { - switch (Opcode) { - case SystemZ::BRAS: return SystemZ::BRASL; - } - return 0; -} - namespace { class SystemZMCAsmBackend : public MCAsmBackend { uint8_t OSABI; @@ -59,14 +50,20 @@ public: LLVM_OVERRIDE; virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value) const LLVM_OVERRIDE; - virtual bool mayNeedRelaxation(const MCInst &Inst) const LLVM_OVERRIDE; + virtual bool mayNeedRelaxation(const MCInst &Inst) const LLVM_OVERRIDE { + return false; + } virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *Fragment, const MCAsmLayout &Layout) const - LLVM_OVERRIDE; + LLVM_OVERRIDE { + return false; + } virtual void relaxInstruction(const MCInst &Inst, - MCInst &Res) const LLVM_OVERRIDE; + MCInst &Res) const LLVM_OVERRIDE { + llvm_unreachable("SystemZ does do not have assembler relaxation"); + } virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const LLVM_OVERRIDE; virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const @@ -114,28 +111,6 @@ void SystemZMCAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, } } -bool SystemZMCAsmBackend::mayNeedRelaxation(const MCInst &Inst) const { - return getRelaxedOpcode(Inst.getOpcode()) != 0; -} - -bool -SystemZMCAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, - const MCRelaxableFragment *Fragment, - const MCAsmLayout &Layout) const { - // At the moment we just need to relax 16-bit fields to wider fields. - Value = extractBitsForFixup(Fixup.getKind(), Value); - return (int16_t)Value != (int64_t)Value; -} - -void SystemZMCAsmBackend::relaxInstruction(const MCInst &Inst, - MCInst &Res) const { - unsigned Opcode = getRelaxedOpcode(Inst.getOpcode()); - assert(Opcode && "Unexpected insn to relax"); - Res = Inst; - Res.setOpcode(Opcode); -} - bool SystemZMCAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { for (uint64_t I = 0; I != Count; ++I) diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp index bda771452f3..f07ea7b31e6 100644 --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp @@ -79,14 +79,6 @@ private: SmallVectorImpl &Fixups) const { return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC32DBL, 2); } - uint64_t getPLT16DBLEncoding(const MCInst &MI, unsigned OpNum, - SmallVectorImpl &Fixups) const { - return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PLT16DBL, 2); - } - uint64_t getPLT32DBLEncoding(const MCInst &MI, unsigned OpNum, - SmallVectorImpl &Fixups) const { - return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PLT32DBL, 2); - } }; } diff --git a/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 84227614c09..3f3ce6bed6a 100644 --- a/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -27,14 +27,36 @@ using namespace llvm; void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { + SystemZMCInstLower Lower(Mang, MF->getContext(), *this); MCInst LoweredMI; switch (MI->getOpcode()) { case SystemZ::Return: LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); break; + case SystemZ::CallBRASL: + LoweredMI = MCInstBuilder(SystemZ::BRASL) + .addReg(SystemZ::R14D) + .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); + break; + + case SystemZ::CallBASR: + LoweredMI = MCInstBuilder(SystemZ::BASR) + .addReg(SystemZ::R14D) + .addReg(MI->getOperand(0).getReg()); + break; + + case SystemZ::CallJG: + LoweredMI = MCInstBuilder(SystemZ::JG) + .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); + break; + + case SystemZ::CallBR: + LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D); + break; + default: - SystemZMCInstLower(Mang, MF->getContext(), *this).lower(MI, LoweredMI); + Lower.lower(MI, LoweredMI); break; } OutStreamer.EmitInstruction(LoweredMI); diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index cb48ca9a474..ec59e2de701 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -223,34 +223,30 @@ defm CondStore64 : CondStores; - def BRASL : InstRIL<0xC05, (outs), (ins pcrel32call:$I2, variable_ops), - "brasl\t%r14, $I2", [(z_call pcrel32call:$I2)]>; - def BASR : InstRR<0x0D, (outs), (ins ADDR64:$R2, variable_ops), - "basr\t%r14, $R2", [(z_call ADDR64:$R2)]>; + F0D, F1D, F2D, F3D, F4D, F5D, F6D, F7D, CC] in { + def CallBRASL : Alias<6, (outs), (ins pcrel32:$I2, variable_ops), + [(z_call pcrel32:$I2)]>; + def CallBASR : Alias<2, (outs), (ins ADDR64:$R2, variable_ops), + [(z_call ADDR64:$R2)]>; } // Sibling calls. Indirect sibling calls must be via R1, since R2 upwards // are argument registers and since branching to R0 is a no-op. -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, - isCodeGenOnly = 1, R1 = 15 in { - def CallJG : InstRIL<0xC04, (outs), (ins pcrel32call:$I2), - "jg\t$I2", [(z_sibcall pcrel32call:$I2)]>; - let R2 = 1, Uses = [R1D] in - def CallBR : InstRR<0x07, (outs), (ins), "br\t%r1", [(z_sibcall R1D)]>; +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { + def CallJG : Alias<6, (outs), (ins pcrel32:$I2), + [(z_sibcall pcrel32:$I2)]>; + let Uses = [R1D] in + def CallBR : Alias<2, (outs), (ins), [(z_sibcall R1D)]>; } // Define the general form of the call instructions for the asm parser. // These instructions don't hard-code %r14 as the return address register. -def AsmBRAS : InstRI<0xA75, (outs), (ins GR64:$R1, brtarget16:$I2), - "bras\t$R1, $I2", []>; -def AsmBRASL : InstRIL<0xC05, (outs), (ins GR64:$R1, brtarget32:$I2), - "brasl\t$R1, $I2", []>; -def AsmBASR : InstRR<0x0D, (outs), (ins GR64:$R1, ADDR64:$R2), - "basr\t$R1, $R2", []>; +def BRAS : InstRI<0xA75, (outs), (ins GR64:$R1, brtarget16:$I2), + "bras\t$R1, $I2", []>; +def BRASL : InstRIL<0xC05, (outs), (ins GR64:$R1, brtarget32:$I2), + "brasl\t$R1, $I2", []>; +def BASR : InstRR<0x0D, (outs), (ins GR64:$R1, ADDR64:$R2), + "basr\t$R1, $R2", []>; //===----------------------------------------------------------------------===// // Move instructions diff --git a/lib/Target/SystemZ/SystemZMCInstLower.cpp b/lib/Target/SystemZ/SystemZMCInstLower.cpp index 432a0d30b62..ebf043e007d 100644 --- a/lib/Target/SystemZ/SystemZMCInstLower.cpp +++ b/lib/Target/SystemZ/SystemZMCInstLower.cpp @@ -15,15 +15,6 @@ using namespace llvm; -// If Opcode is an interprocedural reference that can be shortened, -// return the short form, otherwise return 0. -static unsigned getShortenedInstr(unsigned Opcode) { - switch (Opcode) { - case SystemZ::BRASL: return SystemZ::BRAS; - } - return Opcode; -} - // Return the VK_* enumeration for MachineOperand target flags Flags. static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) { switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) { @@ -39,66 +30,67 @@ SystemZMCInstLower::SystemZMCInstLower(Mangler *mang, MCContext &ctx, SystemZAsmPrinter &asmprinter) : Mang(mang), Ctx(ctx), AsmPrinter(asmprinter) {} -MCOperand SystemZMCInstLower::lowerSymbolOperand(const MachineOperand &MO, - const MCSymbol *Symbol, - int64_t Offset) const { - MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); - const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Kind, Ctx); - if (Offset) { - const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx); - Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx); +const MCExpr * +SystemZMCInstLower::getExpr(const MachineOperand &MO, + MCSymbolRefExpr::VariantKind Kind) const { + const MCSymbol *Symbol; + bool HasOffset = true; + switch (MO.getType()) { + case MachineOperand::MO_MachineBasicBlock: + Symbol = MO.getMBB()->getSymbol(); + HasOffset = false; + break; + + case MachineOperand::MO_GlobalAddress: + Symbol = Mang->getSymbol(MO.getGlobal()); + break; + + case MachineOperand::MO_ExternalSymbol: + Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); + break; + + case MachineOperand::MO_JumpTableIndex: + Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); + HasOffset = false; + break; + + case MachineOperand::MO_ConstantPoolIndex: + Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); + break; + + case MachineOperand::MO_BlockAddress: + Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); + break; + + default: + llvm_unreachable("unknown operand type"); } - return MCOperand::CreateExpr(Expr); + const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Kind, Ctx); + if (HasOffset) + if (int64_t Offset = MO.getOffset()) { + const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx); + Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx); + } + return Expr; } MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const { switch (MO.getType()) { - default: - llvm_unreachable("unknown operand type"); - case MachineOperand::MO_Register: return MCOperand::CreateReg(MO.getReg()); case MachineOperand::MO_Immediate: return MCOperand::CreateImm(MO.getImm()); - case MachineOperand::MO_MachineBasicBlock: - return lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), - /* MO has no offset field */0); - - case MachineOperand::MO_GlobalAddress: - return lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal()), - MO.getOffset()); - - case MachineOperand::MO_ExternalSymbol: { - StringRef Name = MO.getSymbolName(); - return lowerSymbolOperand(MO, AsmPrinter.GetExternalSymbolSymbol(Name), - MO.getOffset()); - } - - case MachineOperand::MO_JumpTableIndex: - return lowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()), - /* MO has no offset field */0); - - case MachineOperand::MO_ConstantPoolIndex: - return lowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()), - MO.getOffset()); - - case MachineOperand::MO_BlockAddress: { - const BlockAddress *BA = MO.getBlockAddress(); - return lowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol(BA), - MO.getOffset()); + default: { + MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); + return MCOperand::CreateExpr(getExpr(MO, Kind)); } } } void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { - unsigned Opcode = MI->getOpcode(); - // When emitting binary code, start with the shortest form of an instruction - // and then relax it where necessary. - if (!AsmPrinter.OutStreamer.hasRawTextSupport()) - Opcode = getShortenedInstr(Opcode); - OutMI.setOpcode(Opcode); + OutMI.setOpcode(MI->getOpcode()); for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); // Ignore all implicit register operands. diff --git a/lib/Target/SystemZ/SystemZMCInstLower.h b/lib/Target/SystemZ/SystemZMCInstLower.h index db5bdb05ab2..33a849d6c77 100644 --- a/lib/Target/SystemZ/SystemZMCInstLower.h +++ b/lib/Target/SystemZ/SystemZMCInstLower.h @@ -10,14 +10,13 @@ #ifndef LLVM_SYSTEMZMCINSTLOWER_H #define LLVM_SYSTEMZMCINSTLOWER_H +#include "llvm/MC/MCExpr.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Compiler.h" namespace llvm { -class MCContext; class MCInst; class MCOperand; -class MCSymbol; class MachineInstr; class MachineOperand; class Mangler; @@ -38,9 +37,9 @@ public: // Return an MCOperand for MO. MCOperand lowerOperand(const MachineOperand& MO) const; - // Return an MCOperand for MO, given that it equals Symbol + Offset. - MCOperand lowerSymbolOperand(const MachineOperand &MO, - const MCSymbol *Symbol, int64_t Offset) const; + // Return an MCExpr for symbolic operand MO with variant kind Kind. + const MCExpr *getExpr(const MachineOperand &MO, + MCSymbolRefExpr::VariantKind Kind) const; }; } // end namespace llvm diff --git a/lib/Target/SystemZ/SystemZOperands.td b/lib/Target/SystemZ/SystemZOperands.td index e1e45412d1f..f1db1fdb4c5 100644 --- a/lib/Target/SystemZ/SystemZOperands.td +++ b/lib/Target/SystemZ/SystemZOperands.td @@ -395,19 +395,6 @@ def pcrel32 : PCRelAddress { let DecoderMethod = "decodePC32DBLOperand"; } -// A PC-relative offset of a global value when the value is used as a -// call target. The offset is sign-extended and multiplied by 2. -def pcrel16call : PCRelAddress { - let PrintMethod = "printCallOperand"; - let EncoderMethod = "getPLT16DBLEncoding"; - let DecoderMethod = "decodePC16DBLOperand"; -} -def pcrel32call : PCRelAddress { - let PrintMethod = "printCallOperand"; - let EncoderMethod = "getPLT32DBLEncoding"; - let DecoderMethod = "decodePC32DBLOperand"; -} - //===----------------------------------------------------------------------===// // Addressing modes //===----------------------------------------------------------------------===//