mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 07:17:36 +00:00
Add a new -enable-cygwin-compatible-output argument, which make the output more
consumably by the cygwin assembler. This is really just a nasty hack until we get real target triple support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7742 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -23,7 +23,7 @@ X86GenInstrInfo.inc: X86.td X86InstrInfo.td ../Target.td $(TBLGEN)
|
|||||||
$(TBLGEN) $< -gen-instr-desc -o $@
|
$(TBLGEN) $< -gen-instr-desc -o $@
|
||||||
|
|
||||||
X86GenInstrSelector.inc: X86.td X86InstrInfo.td ../Target.td $(TBLGEN)
|
X86GenInstrSelector.inc: X86.td X86InstrInfo.td ../Target.td $(TBLGEN)
|
||||||
$(TBLGEN) $< -gen-instr-selector -o $@
|
$(TBLGEN) $< -debug -gen-instr-selector -o $@
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
$(VERB) rm -f *.inc
|
$(VERB) rm -f *.inc
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// This file contains a printer that converts from our internal
|
// This file contains a printer that converts from our internal
|
||||||
// representation of machine-dependent LLVM code to Intel-format
|
// representation of machine-dependent LLVM code to Intel-format
|
||||||
// assembly language. This printer is the output mechanism used
|
// assembly language. This printer is the output mechanism used
|
||||||
// by `llc' and `lli -printmachineinstrs' on X86.
|
// by `llc' and `lli -print-machineinstrs' on X86.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@@ -20,8 +20,14 @@
|
|||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/Support/Mangler.h"
|
#include "llvm/Support/Mangler.h"
|
||||||
#include "Support/StringExtras.h"
|
#include "Support/StringExtras.h"
|
||||||
|
#include "Support/CommandLine.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
// FIXME: This should be automatically picked up by autoconf from the C
|
||||||
|
// frontend
|
||||||
|
cl::opt<bool> EmitCygwin("enable-cygwin-compatible-output", cl::Hidden,
|
||||||
|
cl::desc("Emit X86 assembly code suitable for consumption by cygwin"));
|
||||||
|
|
||||||
struct Printer : public MachineFunctionPass {
|
struct Printer : public MachineFunctionPass {
|
||||||
/// Output stream on which we're printing assembly code.
|
/// Output stream on which we're printing assembly code.
|
||||||
///
|
///
|
||||||
@@ -399,7 +405,8 @@ bool Printer::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
O << "\t.text\n";
|
O << "\t.text\n";
|
||||||
O << "\t.align 16\n";
|
O << "\t.align 16\n";
|
||||||
O << "\t.globl\t" << CurrentFnName << "\n";
|
O << "\t.globl\t" << CurrentFnName << "\n";
|
||||||
O << "\t.type\t" << CurrentFnName << ", @function\n";
|
if (!EmitCygwin)
|
||||||
|
O << "\t.type\t" << CurrentFnName << ", @function\n";
|
||||||
O << CurrentFnName << ":\n";
|
O << CurrentFnName << ":\n";
|
||||||
|
|
||||||
// Number each basic block so that we can consistently refer to them
|
// Number each basic block so that we can consistently refer to them
|
||||||
@@ -455,10 +462,11 @@ void Printer::printOp(const MachineOperand &MO,
|
|||||||
}
|
}
|
||||||
// FALLTHROUGH
|
// FALLTHROUGH
|
||||||
case MachineOperand::MO_MachineRegister:
|
case MachineOperand::MO_MachineRegister:
|
||||||
if (MO.getReg() < MRegisterInfo::FirstVirtualRegister)
|
if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) {
|
||||||
// Bug Workaround: See note in Printer::doInitialization about %.
|
// Bug Workaround: See note in Printer::doInitialization about %.
|
||||||
O << "%" << RI.get(MO.getReg()).Name;
|
if (!EmitCygwin) O << "%";
|
||||||
else
|
O << RI.get(MO.getReg()).Name;
|
||||||
|
} else
|
||||||
O << "%reg" << MO.getReg();
|
O << "%reg" << MO.getReg();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -559,7 +567,7 @@ void Printer::checkImplUses (const TargetInstrDescriptor &Desc) {
|
|||||||
if (Desc.TSFlags & X86II::PrintImplUses) {
|
if (Desc.TSFlags & X86II::PrintImplUses) {
|
||||||
for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
|
for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
|
||||||
// Bug Workaround: See note in Printer::doInitialization about %.
|
// Bug Workaround: See note in Printer::doInitialization about %.
|
||||||
O << ", %" << RI.get(*p).Name;
|
O << ", " << (EmitCygwin ? "" : "%") << RI.get(*p).Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,20 +911,22 @@ void Printer::printMachineInstruction(const MachineInstr *MI) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Printer::doInitialization(Module &M)
|
bool Printer::doInitialization(Module &M) {
|
||||||
{
|
// Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
|
||||||
// Tell gas we are outputting Intel syntax (not AT&T syntax)
|
|
||||||
// assembly.
|
|
||||||
//
|
//
|
||||||
// Bug: gas in `intel_syntax noprefix' mode interprets the symbol
|
// Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
|
||||||
// `Sp' in an instruction as a reference to the register named sp,
|
// instruction as a reference to the register named sp, and if you try to
|
||||||
// and if you try to reference a symbol `Sp' (e.g. `mov ECX, OFFSET
|
// reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
|
||||||
// Sp') then it gets lowercased before being looked up in the symbol
|
// before being looked up in the symbol table. This creates spurious
|
||||||
// table. This creates spurious `undefined symbol' errors when
|
// `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
|
||||||
// linking. Workaround: Do not use `noprefix' mode, and decorate all
|
// mode, and decorate all register names with percent signs.
|
||||||
// register names with percent signs.
|
//
|
||||||
O << "\t.intel_syntax\n";
|
// Cygwin presumably doesn't have this problem, so drop the %'s.
|
||||||
Mang = new Mangler(M);
|
//
|
||||||
|
O << "\t.intel_syntax";
|
||||||
|
if (EmitCygwin) O << " noprefix";
|
||||||
|
O << "\n";
|
||||||
|
Mang = new Mangler(M, EmitCygwin);
|
||||||
return false; // success
|
return false; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// This file contains a printer that converts from our internal
|
// This file contains a printer that converts from our internal
|
||||||
// representation of machine-dependent LLVM code to Intel-format
|
// representation of machine-dependent LLVM code to Intel-format
|
||||||
// assembly language. This printer is the output mechanism used
|
// assembly language. This printer is the output mechanism used
|
||||||
// by `llc' and `lli -printmachineinstrs' on X86.
|
// by `llc' and `lli -print-machineinstrs' on X86.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@@ -20,8 +20,14 @@
|
|||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/Support/Mangler.h"
|
#include "llvm/Support/Mangler.h"
|
||||||
#include "Support/StringExtras.h"
|
#include "Support/StringExtras.h"
|
||||||
|
#include "Support/CommandLine.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
// FIXME: This should be automatically picked up by autoconf from the C
|
||||||
|
// frontend
|
||||||
|
cl::opt<bool> EmitCygwin("enable-cygwin-compatible-output", cl::Hidden,
|
||||||
|
cl::desc("Emit X86 assembly code suitable for consumption by cygwin"));
|
||||||
|
|
||||||
struct Printer : public MachineFunctionPass {
|
struct Printer : public MachineFunctionPass {
|
||||||
/// Output stream on which we're printing assembly code.
|
/// Output stream on which we're printing assembly code.
|
||||||
///
|
///
|
||||||
@@ -399,7 +405,8 @@ bool Printer::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
O << "\t.text\n";
|
O << "\t.text\n";
|
||||||
O << "\t.align 16\n";
|
O << "\t.align 16\n";
|
||||||
O << "\t.globl\t" << CurrentFnName << "\n";
|
O << "\t.globl\t" << CurrentFnName << "\n";
|
||||||
O << "\t.type\t" << CurrentFnName << ", @function\n";
|
if (!EmitCygwin)
|
||||||
|
O << "\t.type\t" << CurrentFnName << ", @function\n";
|
||||||
O << CurrentFnName << ":\n";
|
O << CurrentFnName << ":\n";
|
||||||
|
|
||||||
// Number each basic block so that we can consistently refer to them
|
// Number each basic block so that we can consistently refer to them
|
||||||
@@ -455,10 +462,11 @@ void Printer::printOp(const MachineOperand &MO,
|
|||||||
}
|
}
|
||||||
// FALLTHROUGH
|
// FALLTHROUGH
|
||||||
case MachineOperand::MO_MachineRegister:
|
case MachineOperand::MO_MachineRegister:
|
||||||
if (MO.getReg() < MRegisterInfo::FirstVirtualRegister)
|
if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) {
|
||||||
// Bug Workaround: See note in Printer::doInitialization about %.
|
// Bug Workaround: See note in Printer::doInitialization about %.
|
||||||
O << "%" << RI.get(MO.getReg()).Name;
|
if (!EmitCygwin) O << "%";
|
||||||
else
|
O << RI.get(MO.getReg()).Name;
|
||||||
|
} else
|
||||||
O << "%reg" << MO.getReg();
|
O << "%reg" << MO.getReg();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -559,7 +567,7 @@ void Printer::checkImplUses (const TargetInstrDescriptor &Desc) {
|
|||||||
if (Desc.TSFlags & X86II::PrintImplUses) {
|
if (Desc.TSFlags & X86II::PrintImplUses) {
|
||||||
for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
|
for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
|
||||||
// Bug Workaround: See note in Printer::doInitialization about %.
|
// Bug Workaround: See note in Printer::doInitialization about %.
|
||||||
O << ", %" << RI.get(*p).Name;
|
O << ", " << (EmitCygwin ? "" : "%") << RI.get(*p).Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,20 +911,22 @@ void Printer::printMachineInstruction(const MachineInstr *MI) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Printer::doInitialization(Module &M)
|
bool Printer::doInitialization(Module &M) {
|
||||||
{
|
// Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
|
||||||
// Tell gas we are outputting Intel syntax (not AT&T syntax)
|
|
||||||
// assembly.
|
|
||||||
//
|
//
|
||||||
// Bug: gas in `intel_syntax noprefix' mode interprets the symbol
|
// Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
|
||||||
// `Sp' in an instruction as a reference to the register named sp,
|
// instruction as a reference to the register named sp, and if you try to
|
||||||
// and if you try to reference a symbol `Sp' (e.g. `mov ECX, OFFSET
|
// reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
|
||||||
// Sp') then it gets lowercased before being looked up in the symbol
|
// before being looked up in the symbol table. This creates spurious
|
||||||
// table. This creates spurious `undefined symbol' errors when
|
// `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
|
||||||
// linking. Workaround: Do not use `noprefix' mode, and decorate all
|
// mode, and decorate all register names with percent signs.
|
||||||
// register names with percent signs.
|
//
|
||||||
O << "\t.intel_syntax\n";
|
// Cygwin presumably doesn't have this problem, so drop the %'s.
|
||||||
Mang = new Mangler(M);
|
//
|
||||||
|
O << "\t.intel_syntax";
|
||||||
|
if (EmitCygwin) O << " noprefix";
|
||||||
|
O << "\n";
|
||||||
|
Mang = new Mangler(M, EmitCygwin);
|
||||||
return false; // success
|
return false; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user