mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
Adding working version of assembly parser for the MBlaze backend
Major cleanup of whitespace and formatting issues in MBlaze backend git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118434 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -56,38 +56,38 @@ static unsigned mblazeBinary2Opcode[] = {
|
||||
MBlaze::SBI, MBlaze::SHI, MBlaze::SWI, UNSUPPORTED, //3C,3D,3E,3F
|
||||
};
|
||||
|
||||
static unsigned getRD( uint32_t insn ) {
|
||||
return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>21)&0x1F );
|
||||
static unsigned getRD(uint32_t insn) {
|
||||
return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>21)&0x1F);
|
||||
}
|
||||
|
||||
static unsigned getRA( uint32_t insn ) {
|
||||
return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>16)&0x1F );
|
||||
static unsigned getRA(uint32_t insn) {
|
||||
return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F);
|
||||
}
|
||||
|
||||
static unsigned getRB( uint32_t insn ) {
|
||||
return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>11)&0x1F );
|
||||
static unsigned getRB(uint32_t insn) {
|
||||
return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F);
|
||||
}
|
||||
|
||||
static int64_t getRS( uint32_t insn ) {
|
||||
static int64_t getRS(uint32_t insn) {
|
||||
int16_t val = (insn & 0x3FFF);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int64_t getIMM( uint32_t insn ) {
|
||||
static int64_t getIMM(uint32_t insn) {
|
||||
int16_t val = (insn & 0xFFFF);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int64_t getSHT( uint32_t insn ) {
|
||||
static int64_t getSHT(uint32_t insn) {
|
||||
int16_t val = (insn & 0x1F);
|
||||
return val;
|
||||
}
|
||||
|
||||
static unsigned getFLAGS( int32_t insn ) {
|
||||
static unsigned getFLAGS(int32_t insn) {
|
||||
return (insn & 0x7FF);
|
||||
}
|
||||
|
||||
static int64_t getFSL( uint32_t insn ) {
|
||||
static int64_t getFSL(uint32_t insn) {
|
||||
int16_t val = (insn & 0xF);
|
||||
return val;
|
||||
}
|
||||
@@ -412,7 +412,7 @@ static unsigned decodeRTSD(uint32_t insn) {
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned getOPCODE( uint32_t insn ) {
|
||||
static unsigned getOPCODE(uint32_t insn) {
|
||||
unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
|
||||
switch (opcode) {
|
||||
case MBlaze::MUL: return decodeMUL(insn);
|
||||
@@ -465,102 +465,99 @@ bool MBlazeDisassembler::getInstruction(MCInst &instr,
|
||||
|
||||
// Get the MCInst opcode from the binary instruction and make sure
|
||||
// that it is a valid instruction.
|
||||
unsigned opcode = getOPCODE( insn );
|
||||
if( opcode == UNSUPPORTED )
|
||||
unsigned opcode = getOPCODE(insn);
|
||||
if (opcode == UNSUPPORTED)
|
||||
return false;
|
||||
|
||||
instr.setOpcode(opcode);
|
||||
|
||||
uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
|
||||
switch( (tsFlags & MBlazeII::FormMask) ) {
|
||||
default:
|
||||
errs() << "Opcode: " << MBlazeInsts[opcode].Name << "\n";
|
||||
errs() << "Flags: "; errs().write_hex( tsFlags ); errs() << "\n";
|
||||
return false;
|
||||
switch ((tsFlags & MBlazeII::FormMask)) {
|
||||
default: llvm_unreachable("unknown instruction encoding");
|
||||
|
||||
case MBlazeII::FRRR:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRRI:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCRR:
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCRI:
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRCR:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRCI:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCCR:
|
||||
instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCCI:
|
||||
instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRRCI:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getSHT(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRRC:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRCX:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRCS:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getRS(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getRS(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCRCS:
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getRS(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getRS(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCRCX:
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCX:
|
||||
instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FCR:
|
||||
instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRB(insn)));
|
||||
break;
|
||||
|
||||
case MBlazeII::FRIR:
|
||||
instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
|
||||
instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
|
||||
instr.addOperand(MCOperand::CreateReg(getRD(insn)));
|
||||
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
|
||||
instr.addOperand(MCOperand::CreateReg(getRA(insn)));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -102,7 +102,7 @@ void MBlazeInstPrinter::printUnsignedImm(const MCInst *MI, int OpNo,
|
||||
}
|
||||
|
||||
void MBlazeInstPrinter::printMemOperand(const MCInst *MI, int OpNo,
|
||||
raw_ostream &O, const char *Modifier ) {
|
||||
raw_ostream &O, const char *Modifier) {
|
||||
printOperand(MI, OpNo+1, O, NULL);
|
||||
O << ", ";
|
||||
printOperand(MI, OpNo, O, NULL);
|
||||
|
@@ -70,8 +70,8 @@ bool MBlazeAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
if ((Count % 4) != 0)
|
||||
return false;
|
||||
|
||||
for (uint64_t i = 0; i < Count; i += 4 )
|
||||
OW->Write32( 0x00000000 );
|
||||
for (uint64_t i = 0; i < Count; i += 4)
|
||||
OW->Write32(0x00000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -114,17 +114,17 @@ public:
|
||||
void ELFMBlazeAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
|
||||
uint64_t Value) const {
|
||||
unsigned Size = getFixupKindSize(Fixup.getKind());
|
||||
|
||||
|
||||
assert(Fixup.getOffset() + Size <= DF.getContents().size() &&
|
||||
"Invalid fixup offset!");
|
||||
|
||||
char *data = DF.getContents().data() + Fixup.getOffset();
|
||||
switch (Size) {
|
||||
default: llvm_unreachable( "Cannot fixup unknown value." );
|
||||
case 1: llvm_unreachable( "Cannot fixup 1 byte value." );
|
||||
case 8: llvm_unreachable( "Cannot fixup 8 byte value." );
|
||||
default: llvm_unreachable("Cannot fixup unknown value.");
|
||||
case 1: llvm_unreachable("Cannot fixup 1 byte value.");
|
||||
case 8: llvm_unreachable("Cannot fixup 8 byte value.");
|
||||
|
||||
case 4:
|
||||
case 4:
|
||||
*(data+7) = uint8_t(Value);
|
||||
*(data+6) = uint8_t(Value >> 8);
|
||||
*(data+3) = uint8_t(Value >> 16);
|
||||
|
@@ -69,7 +69,7 @@ namespace {
|
||||
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
|
||||
const char *Modifier = 0);
|
||||
|
||||
void EmitInstruction(const MachineInstr *MI);
|
||||
void EmitInstruction(const MachineInstr *MI);
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
|
@@ -1,16 +1,16 @@
|
||||
//===- MBlazeCallingConv.td - Calling Conventions for MBlaze -*- tablegen -*-=//
|
||||
//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This describes the calling conventions for MBlaze architecture.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// CCIfSubtarget - Match if the current subtarget has a feature F.
|
||||
class CCIfSubtarget<string F, CCAction A>:
|
||||
class CCIfSubtarget<string F, CCAction A>:
|
||||
CCIf<!strconcat("State.getTarget().getSubtarget<MBlazeSubtarget>().", F), A>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@@ -36,7 +36,7 @@ namespace {
|
||||
const TargetInstrInfo *TII;
|
||||
|
||||
static char ID;
|
||||
Filler(TargetMachine &tm)
|
||||
Filler(TargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
@@ -56,44 +56,44 @@ namespace {
|
||||
char Filler::ID = 0;
|
||||
} // end of anonymous namespace
|
||||
|
||||
static bool hasImmInstruction( MachineBasicBlock::iterator &candidate ) {
|
||||
static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) {
|
||||
// Any instruction with an immediate mode operand greater than
|
||||
// 16-bits requires an implicit IMM instruction.
|
||||
unsigned numOper = candidate->getNumOperands();
|
||||
for( unsigned op = 0; op < numOper; ++op ) {
|
||||
if( candidate->getOperand(op).isImm() &&
|
||||
(candidate->getOperand(op).getImm() & 0xFFFFFFFFFFFF0000LL) != 0 )
|
||||
for (unsigned op = 0; op < numOper; ++op) {
|
||||
if (candidate->getOperand(op).isImm() &&
|
||||
(candidate->getOperand(op).getImm() & 0xFFFFFFFFFFFF0000LL) != 0)
|
||||
return true;
|
||||
|
||||
// FIXME: we could probably check to see if the FP value happens
|
||||
// to not need an IMM instruction. For now we just always
|
||||
// assume that FP values always do.
|
||||
if( candidate->getOperand(op).isFPImm() )
|
||||
if (candidate->getOperand(op).isFPImm())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool delayHasHazard( MachineBasicBlock::iterator &candidate,
|
||||
MachineBasicBlock::iterator &slot ) {
|
||||
static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
|
||||
MachineBasicBlock::iterator &slot) {
|
||||
|
||||
// Loop over all of the operands in the branch instruction
|
||||
// and make sure that none of them are defined by the
|
||||
// candidate instruction.
|
||||
unsigned numOper = slot->getNumOperands();
|
||||
for( unsigned op = 0; op < numOper; ++op ) {
|
||||
if( !slot->getOperand(op).isReg() ||
|
||||
for (unsigned op = 0; op < numOper; ++op) {
|
||||
if (!slot->getOperand(op).isReg() ||
|
||||
!slot->getOperand(op).isUse() ||
|
||||
slot->getOperand(op).isImplicit() )
|
||||
slot->getOperand(op).isImplicit())
|
||||
continue;
|
||||
|
||||
unsigned cnumOper = candidate->getNumOperands();
|
||||
for( unsigned cop = 0; cop < cnumOper; ++cop ) {
|
||||
if( candidate->getOperand(cop).isReg() &&
|
||||
for (unsigned cop = 0; cop < cnumOper; ++cop) {
|
||||
if (candidate->getOperand(cop).isReg() &&
|
||||
candidate->getOperand(cop).isDef() &&
|
||||
candidate->getOperand(cop).getReg() ==
|
||||
slot->getOperand(op).getReg() )
|
||||
candidate->getOperand(cop).getReg() ==
|
||||
slot->getOperand(op).getReg())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -102,20 +102,20 @@ static bool delayHasHazard( MachineBasicBlock::iterator &candidate,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool usedBeforeDelaySlot( MachineBasicBlock::iterator &candidate,
|
||||
MachineBasicBlock::iterator &slot ) {
|
||||
static bool usedBeforeDelaySlot(MachineBasicBlock::iterator &candidate,
|
||||
MachineBasicBlock::iterator &slot) {
|
||||
MachineBasicBlock::iterator I = candidate;
|
||||
for (++I; I != slot; ++I) {
|
||||
unsigned numOper = I->getNumOperands();
|
||||
for( unsigned op = 0; op < numOper; ++op ) {
|
||||
if( I->getOperand(op).isReg() &&
|
||||
I->getOperand(op).isUse() ) {
|
||||
for (unsigned op = 0; op < numOper; ++op) {
|
||||
if (I->getOperand(op).isReg() &&
|
||||
I->getOperand(op).isUse()) {
|
||||
unsigned reg = I->getOperand(op).getReg();
|
||||
unsigned cops = candidate->getNumOperands();
|
||||
for( unsigned cop = 0; cop < cops; ++cop ) {
|
||||
if( candidate->getOperand(cop).isReg() &&
|
||||
for (unsigned cop = 0; cop < cops; ++cop) {
|
||||
if (candidate->getOperand(cop).isReg() &&
|
||||
candidate->getOperand(cop).isDef() &&
|
||||
candidate->getOperand(cop).getReg() == reg )
|
||||
candidate->getOperand(cop).getReg() == reg)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -130,9 +130,9 @@ findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator &slot) {
|
||||
MachineBasicBlock::iterator found = MBB.end();
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(); I != slot; ++I) {
|
||||
TargetInstrDesc desc = I->getDesc();
|
||||
if( desc.hasDelaySlot() || desc.isBranch() ||
|
||||
desc.mayLoad() || desc. mayStore() ||
|
||||
hasImmInstruction(I) || delayHasHazard(I,slot) ||
|
||||
if (desc.hasDelaySlot() || desc.isBranch() ||
|
||||
desc.mayLoad() || desc. mayStore() ||
|
||||
hasImmInstruction(I) || delayHasHazard(I,slot) ||
|
||||
usedBeforeDelaySlot(I,slot)) continue;
|
||||
|
||||
found = I;
|
||||
@@ -155,10 +155,10 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
|
||||
++FilledSlots;
|
||||
Changed = true;
|
||||
|
||||
if( D == MBB.end() )
|
||||
if (D == MBB.end())
|
||||
BuildMI(MBB, J, I->getDebugLoc(), TII->get(MBlaze::NOP));
|
||||
else
|
||||
MBB.splice( J, &MBB, D );
|
||||
MBB.splice(J, &MBB, D);
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ MBlazeELFWriterInfo::MBlazeELFWriterInfo(TargetMachine &TM)
|
||||
MBlazeELFWriterInfo::~MBlazeELFWriterInfo() {}
|
||||
|
||||
unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
|
||||
switch(MachineRelTy) {
|
||||
switch (MachineRelTy) {
|
||||
case MBlaze::reloc_pcrel_word:
|
||||
return R_MICROBLAZE_64_PCREL;
|
||||
case MBlaze::reloc_absolute_word:
|
||||
@@ -45,7 +45,7 @@ unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
|
||||
|
||||
long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
|
||||
long int Modifier) const {
|
||||
switch(RelTy) {
|
||||
switch (RelTy) {
|
||||
case R_MICROBLAZE_32_PCREL:
|
||||
return Modifier - 4;
|
||||
case R_MICROBLAZE_32:
|
||||
@@ -58,7 +58,7 @@ long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
|
||||
|
||||
unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
|
||||
// FIXME: Most of these sizes are guesses based on the name
|
||||
switch(RelTy) {
|
||||
switch (RelTy) {
|
||||
case R_MICROBLAZE_32:
|
||||
case R_MICROBLAZE_32_PCREL:
|
||||
case R_MICROBLAZE_32_PCREL_LO:
|
||||
@@ -83,7 +83,7 @@ unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
|
||||
|
||||
bool MBlazeELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
|
||||
// FIXME: Most of these are guesses based on the name
|
||||
switch(RelTy) {
|
||||
switch (RelTy) {
|
||||
case R_MICROBLAZE_32_PCREL:
|
||||
case R_MICROBLAZE_64_PCREL:
|
||||
case R_MICROBLAZE_32_PCREL_LO:
|
||||
|
@@ -31,7 +31,7 @@ namespace llvm {
|
||||
R_MICROBLAZE_32_LO = 6,
|
||||
R_MICROBLAZE_SRO32 = 7,
|
||||
R_MICROBLAZE_SRW32 = 8,
|
||||
R_MICROBLAZE_64_NONE = 9,
|
||||
R_MICROBLAZE_64_NONE = 9,
|
||||
R_MICROBLAZE_32_SYM_OP_SYM = 10,
|
||||
R_MICROBLAZE_GNU_VTINHERIT = 11,
|
||||
R_MICROBLAZE_GNU_VTENTRY = 12,
|
||||
|
@@ -159,7 +159,6 @@ SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) {
|
||||
} else {
|
||||
Base = N.getOperand(0);
|
||||
}
|
||||
DEBUG( errs() << "WESLEY: Using Operand Immediate\n" );
|
||||
return true; // [r+i]
|
||||
}
|
||||
} else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
|
||||
@@ -167,7 +166,6 @@ SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) {
|
||||
uint32_t Imm = CN->getZExtValue();
|
||||
Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0));
|
||||
Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0));
|
||||
DEBUG( errs() << "WESLEY: Using Constant Node\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -192,20 +190,15 @@ SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) {
|
||||
unsigned Opcode = Node->getOpcode();
|
||||
DebugLoc dl = Node->getDebugLoc();
|
||||
|
||||
// Dump information about the Node being selected
|
||||
DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
|
||||
|
||||
// If we have a custom node, we already have selected!
|
||||
if (Node->isMachineOpcode()) {
|
||||
DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
|
||||
if (Node->isMachineOpcode())
|
||||
return NULL;
|
||||
}
|
||||
|
||||
///
|
||||
// Instruction Selection not handled by the auto-generated
|
||||
// tablegen selection should be handled here.
|
||||
///
|
||||
switch(Opcode) {
|
||||
switch (Opcode) {
|
||||
default: break;
|
||||
|
||||
// Get target GOT address.
|
||||
@@ -235,8 +228,8 @@ SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) {
|
||||
SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32);
|
||||
SDValue InFlag(0, 0);
|
||||
|
||||
if ( (isa<GlobalAddressSDNode>(Callee)) ||
|
||||
(isa<ExternalSymbolSDNode>(Callee)) )
|
||||
if ((isa<GlobalAddressSDNode>(Callee)) ||
|
||||
(isa<ExternalSymbolSDNode>(Callee)))
|
||||
{
|
||||
/// Direct call for global addresses and external symbols
|
||||
SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32);
|
||||
|
@@ -290,7 +290,7 @@ MBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
else if (MI->getOpcode() == MBlaze::ShiftRL)
|
||||
BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST);
|
||||
else
|
||||
llvm_unreachable( "Cannot lower unknown shift instruction" );
|
||||
llvm_unreachable("Cannot lower unknown shift instruction");
|
||||
|
||||
BuildMI(loop, dl, TII->get(MBlaze::ADDI), NAMT)
|
||||
.addReg(SAMT)
|
||||
@@ -332,7 +332,7 @@ MBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
|
||||
unsigned Opc;
|
||||
switch (MI->getOperand(4).getImm()) {
|
||||
default: llvm_unreachable( "Unknown branch condition" );
|
||||
default: llvm_unreachable("Unknown branch condition");
|
||||
case MBlazeCC::EQ: Opc = MBlaze::BNEID; break;
|
||||
case MBlazeCC::NE: Opc = MBlaze::BEQID; break;
|
||||
case MBlazeCC::GT: Opc = MBlaze::BLEID; break;
|
||||
@@ -396,9 +396,9 @@ SDValue MBlazeTargetLowering::LowerSELECT_CC(SDValue Op,
|
||||
CompareFlag = DAG.getNode(MBlazeISD::ICmp, dl, MVT::i32, LHS, RHS)
|
||||
.getValue(1);
|
||||
} else {
|
||||
llvm_unreachable( "Cannot lower select_cc with unknown type" );
|
||||
llvm_unreachable("Cannot lower select_cc with unknown type");
|
||||
}
|
||||
|
||||
|
||||
return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
|
||||
CompareFlag);
|
||||
}
|
||||
@@ -429,7 +429,7 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT PtrVT = Op.getValueType();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
|
||||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, 0 );
|
||||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, 0);
|
||||
return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, JTI);
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
|
||||
N->getOffset(), 0 );
|
||||
N->getOffset(), 0);
|
||||
return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP);
|
||||
}
|
||||
|
||||
@@ -616,10 +616,10 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
|
||||
// node so that legalize doesn't hack it.
|
||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,
|
||||
getPointerTy(), 0, 0 );
|
||||
getPointerTy(), 0, 0);
|
||||
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
|
||||
Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
|
||||
getPointerTy(), 0 );
|
||||
getPointerTy(), 0);
|
||||
|
||||
// MBlazeJmpLink = #chain, #target_address, #opt_in_flags...
|
||||
// = Chain, Callee, Reg#1, Reg#2, ...
|
||||
@@ -675,7 +675,7 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv,
|
||||
RVLocs[i].getValVT(), InFlag).getValue(1);
|
||||
InFlag = Chain.getValue(2);
|
||||
InVals.push_back(Chain.getValue(0));
|
||||
}
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
@@ -785,7 +785,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
|
||||
// To meet ABI, when VARARGS are passed on registers, the registers
|
||||
// must have their values written to the caller stack frame. If the last
|
||||
// argument was placed in the stack, there's no need to save any register.
|
||||
// argument was placed in the stack, there's no need to save any register.
|
||||
if ((isVarArg) && ArgRegEnd) {
|
||||
if (StackPtr.getNode() == 0)
|
||||
StackPtr = DAG.getRegister(StackReg, getPointerTy());
|
||||
@@ -817,7 +817,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
}
|
||||
}
|
||||
|
||||
// All stores are grouped in one node to allow the matching between
|
||||
// All stores are grouped in one node to allow the matching between
|
||||
// the size of Ins and InVals. This only happens when on varg functions
|
||||
if (!OutChains.empty()) {
|
||||
OutChains.push_back(Chain);
|
||||
|
@@ -100,11 +100,11 @@ let Predicates=[HasFPU] in {
|
||||
def FMUL : ArithF<0x16, 0x100, "fmul ", fmul, IIAlu>;
|
||||
def FDIV : ArithF<0x16, 0x180, "fdiv ", fdiv, IIAlu>;
|
||||
|
||||
def LWF : LoadFM<0x32, "lw ", load>;
|
||||
def LWFI : LoadFMI<0x32, "lwi ", load>;
|
||||
def LWF : LoadFM<0x32, "lw ", load>;
|
||||
def LWFI : LoadFMI<0x32, "lwi ", load>;
|
||||
|
||||
def SWF : StoreFM<0x32, "sw ", store>;
|
||||
def SWFI : StoreFMI<0x32, "swi ", store>;
|
||||
def SWF : StoreFM<0x32, "sw ", store>;
|
||||
def SWFI : StoreFMI<0x32, "swi ", store>;
|
||||
}
|
||||
|
||||
let Predicates=[HasFPU,HasSqrt] in {
|
||||
|
@@ -58,8 +58,8 @@ class MBlazeInst<bits<6> op, Format form, dag outs, dag ins, string asmstr,
|
||||
bits<6> FormBits = Form.Value;
|
||||
|
||||
// Top 6 bits are the 'opcode' field
|
||||
let Inst{0-5} = opcode;
|
||||
|
||||
let Inst{0-5} = opcode;
|
||||
|
||||
// If the instruction is marked as a pseudo, set isCodeGenOnly so that the
|
||||
// assembler and disassmbler ignore it.
|
||||
let isCodeGenOnly = !eq(!cast<string>(form), "FPseudo");
|
||||
@@ -86,15 +86,15 @@ class MBlazePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class TA<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin> :
|
||||
MBlazeInst<op,FRRR,outs, ins, asmstr, pattern, itin>
|
||||
list<dag> pattern, InstrItinClass itin> :
|
||||
MBlazeInst<op,FRRR,outs, ins, asmstr, pattern, itin>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> ra;
|
||||
bits<5> rb;
|
||||
|
||||
let Inst{6-10} = rd;
|
||||
let Inst{11-15} = ra;
|
||||
let Inst{11-15} = ra;
|
||||
let Inst{16-20} = rb;
|
||||
let Inst{21-31} = flags;
|
||||
}
|
||||
@@ -104,15 +104,15 @@ class TA<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin> :
|
||||
MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin> :
|
||||
MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> ra;
|
||||
bits<16> imm16;
|
||||
|
||||
let Inst{6-10} = rd;
|
||||
let Inst{11-15} = ra;
|
||||
let Inst{11-15} = ra;
|
||||
let Inst{16-31} = imm16;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
// the LLVM DAG : <|opcode|rd|ra|immediate|>
|
||||
//===----------------------------------------------------------------------===//
|
||||
class TBR<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin> :
|
||||
InstrItinClass itin> :
|
||||
TB<op, outs, ins, asmstr, pattern, itin> {
|
||||
bits<5> rrd;
|
||||
bits<16> rimm16;
|
||||
|
@@ -64,6 +64,16 @@ def HasMMU : Predicate<"Subtarget.hasMMU()">;
|
||||
// MBlaze Operand, Complex Patterns and Transformations Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def MBlazeMemAsmOperand : AsmOperandClass {
|
||||
let Name = "Mem";
|
||||
let SuperClasses = [];
|
||||
}
|
||||
|
||||
def MBlazeFslAsmOperand : AsmOperandClass {
|
||||
let Name = "Fsl";
|
||||
let SuperClasses = [];
|
||||
}
|
||||
|
||||
// Instruction operand types
|
||||
def brtarget : Operand<OtherVT>;
|
||||
def calltarget : Operand<i32>;
|
||||
@@ -79,17 +89,20 @@ def uimm16 : Operand<i32> {
|
||||
// FSL Operand
|
||||
def fslimm : Operand<i32> {
|
||||
let PrintMethod = "printFSLImm";
|
||||
let ParserMatchClass = MBlazeFslAsmOperand;
|
||||
}
|
||||
|
||||
// Address operand
|
||||
def memri : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops simm16, GPR);
|
||||
let ParserMatchClass = MBlazeMemAsmOperand;
|
||||
}
|
||||
|
||||
def memrr : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops GPR, GPR);
|
||||
let ParserMatchClass = MBlazeMemAsmOperand;
|
||||
}
|
||||
|
||||
// Node immediate fits as 16-bit sign extended on target immediate.
|
||||
@@ -490,31 +503,31 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
|
||||
hasCtrlDep=1, rd=0x10, Form=FCRI in {
|
||||
def RTSD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
|
||||
"rtsd $target, $imm",
|
||||
[],
|
||||
[],
|
||||
IIBranch>;
|
||||
}
|
||||
|
||||
let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
|
||||
hasCtrlDep=1, rd=0x11, Form=FCRI in {
|
||||
def RTID : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
|
||||
"rtsd $target, $imm",
|
||||
[],
|
||||
"rtid $target, $imm",
|
||||
[],
|
||||
IIBranch>;
|
||||
}
|
||||
|
||||
let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
|
||||
hasCtrlDep=1, rd=0x12, Form=FCRI in {
|
||||
def RTBD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
|
||||
"rtsd $target, $imm",
|
||||
[],
|
||||
"rtbd $target, $imm",
|
||||
[],
|
||||
IIBranch>;
|
||||
}
|
||||
|
||||
let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
|
||||
hasCtrlDep=1, rd=0x14, Form=FCRI in {
|
||||
def RTED : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
|
||||
"rtsd $target, $imm",
|
||||
[],
|
||||
"rted $target, $imm",
|
||||
[],
|
||||
IIBranch>;
|
||||
}
|
||||
|
||||
@@ -551,20 +564,20 @@ let usesCustomInserter = 1 in {
|
||||
|
||||
let rb = 0 in {
|
||||
def SEXT16 : TA<0x24, 0x061, (outs GPR:$dst), (ins GPR:$src),
|
||||
"sext16 $dst, $src", [], IIAlu>;
|
||||
"sext16 $dst, $src", [], IIAlu>;
|
||||
def SEXT8 : TA<0x24, 0x060, (outs GPR:$dst), (ins GPR:$src),
|
||||
"sext8 $dst, $src", [], IIAlu>;
|
||||
"sext8 $dst, $src", [], IIAlu>;
|
||||
def SRL : TA<0x24, 0x041, (outs GPR:$dst), (ins GPR:$src),
|
||||
"srl $dst, $src", [], IIAlu>;
|
||||
"srl $dst, $src", [], IIAlu>;
|
||||
def SRA : TA<0x24, 0x001, (outs GPR:$dst), (ins GPR:$src),
|
||||
"sra $dst, $src", [], IIAlu>;
|
||||
"sra $dst, $src", [], IIAlu>;
|
||||
def SRC : TA<0x24, 0x021, (outs GPR:$dst), (ins GPR:$src),
|
||||
"src $dst, $src", [], IIAlu>;
|
||||
"src $dst, $src", [], IIAlu>;
|
||||
}
|
||||
|
||||
let opcode=0x08, isCodeGenOnly=1 in {
|
||||
def LEA_ADDI : TB<0x08, (outs GPR:$dst), (ins memri:$addr),
|
||||
"addi $dst, ${addr:stackloc}",
|
||||
"addi $dst, ${addr:stackloc}",
|
||||
[(set GPR:$dst, iaddr:$addr)], IIAlu>;
|
||||
}
|
||||
|
||||
@@ -584,7 +597,7 @@ def MSRCLR : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrclr", [], IIAlu> {
|
||||
}
|
||||
|
||||
let rd=0x0, Form=FCRR in {
|
||||
def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b),
|
||||
def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b),
|
||||
"wdc $a, $b", [], IIAlu>;
|
||||
def WDCF : TA<0x24, 0x74, (outs), (ins GPR:$a, GPR:$b),
|
||||
"wdc.flush $a, $b", [], IIAlu>;
|
||||
@@ -597,7 +610,7 @@ let rd=0x0, Form=FCRR in {
|
||||
def BRK : Branch<0x26, 0x0C, 0x000, "brk ">;
|
||||
def BRKI : BranchI<0x2E, 0x0C, "brki ">;
|
||||
|
||||
def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm),
|
||||
def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm),
|
||||
"imm $imm", [], IIAlu>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -633,42 +646,42 @@ def : Pat<(srl GPR:$L, GPR:$R), (ShiftRL GPR:$L, GPR:$R)>;
|
||||
|
||||
// SET_CC operations
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETEQ),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMP GPR:$L, GPR:$R), 1)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETNE),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMP GPR:$L, GPR:$R), 2)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETGT),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMP GPR:$L, GPR:$R), 3)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETLT),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMP GPR:$L, GPR:$R), 4)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETGE),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMP GPR:$L, GPR:$R), 5)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETLE),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMP GPR:$L, GPR:$R), 6)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETUGT),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMPU GPR:$L, GPR:$R), 3)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETULT),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMPU GPR:$L, GPR:$R), 4)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETUGE),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMPU GPR:$L, GPR:$R), 5)>;
|
||||
def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETULE),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0),
|
||||
(CMPU GPR:$L, GPR:$R), 6)>;
|
||||
|
||||
// SELECT operations
|
||||
def : Pat<(select (i32 GPR:$C), (i32 GPR:$T), (i32 GPR:$F)),
|
||||
(Select_CC GPR:$T, GPR:$F, GPR:$C, 2)>;
|
||||
|
||||
// SELECT_CC
|
||||
def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R),
|
||||
// SELECT_CC
|
||||
def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R),
|
||||
(i32 GPR:$T), (i32 GPR:$F), SETEQ),
|
||||
(Select_CC GPR:$T, GPR:$F, (CMP GPR:$L, GPR:$R), 1)>;
|
||||
def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R),
|
||||
|
@@ -48,7 +48,7 @@ std::string MBlazeIntrinsicInfo::getName(unsigned IntrID, const Type **Tys,
|
||||
assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
|
||||
if (IntrID < Intrinsic::num_intrinsics)
|
||||
return 0;
|
||||
assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics &&
|
||||
assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics &&
|
||||
"Invalid intrinsic ID");
|
||||
|
||||
std::string Result(names[IntrID - Intrinsic::num_intrinsics]);
|
||||
@@ -94,12 +94,12 @@ static const FunctionType *getType(LLVMContext &Context, unsigned id) {
|
||||
const Type *ResultTy = NULL;
|
||||
std::vector<const Type*> ArgTys;
|
||||
bool IsVarArg = false;
|
||||
|
||||
|
||||
#define GET_INTRINSIC_GENERATOR
|
||||
#include "MBlazeGenIntrinsics.inc"
|
||||
#undef GET_INTRINSIC_GENERATOR
|
||||
|
||||
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
|
||||
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
|
||||
}
|
||||
|
||||
Function *MBlazeIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
//===- IntrinsicsMBlaze.td - Defines MBlaze intrinsics -----*- tablegen -*-===//
|
||||
//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines all of the MicroBlaze-specific intrinsics.
|
||||
@@ -16,7 +16,7 @@
|
||||
//
|
||||
|
||||
// MBlaze intrinsic classes.
|
||||
let TargetPrefix = "mblaze", isTarget = 1 in {
|
||||
let TargetPrefix = "mblaze", isTarget = 1 in {
|
||||
class MBFSL_Get_Intrinsic : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
|
||||
|
||||
class MBFSL_Put_Intrinsic : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>;
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class Target;
|
||||
|
||||
|
||||
class MBlazeMCAsmInfo : public MCAsmInfo {
|
||||
public:
|
||||
explicit MBlazeMCAsmInfo();
|
||||
|
@@ -94,7 +94,7 @@ public:
|
||||
|
||||
void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
|
||||
raw_ostream &OS) const {
|
||||
assert(Size <= 8 && "size too big in emit constant" );
|
||||
assert(Size <= 8 && "size too big in emit constant");
|
||||
|
||||
for (unsigned i = 0; i != Size; ++i) {
|
||||
EmitByte(Val & 255, CurByte, OS);
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
}
|
||||
|
||||
void EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const;
|
||||
void EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte,
|
||||
void EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte,
|
||||
raw_ostream &OS) const;
|
||||
|
||||
void EmitImmediate(const MCInst &MI,
|
||||
@@ -132,7 +132,7 @@ unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI,
|
||||
return MBlazeRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||
else if (MO.isImm())
|
||||
return static_cast<unsigned>(MO.getImm());
|
||||
else if (MO.isExpr() )
|
||||
else if (MO.isExpr())
|
||||
return 0; // The relocation has already been recorded at this point.
|
||||
else {
|
||||
#ifndef NDEBUG
|
||||
@@ -146,7 +146,7 @@ unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI,
|
||||
void MBlazeMCCodeEmitter::
|
||||
EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const {
|
||||
int32_t val = (int32_t)imm.getImm();
|
||||
if (val > 32767 || val < -32678 ) {
|
||||
if (val > 32767 || val < -32678) {
|
||||
EmitByte(0x0D, CurByte, OS);
|
||||
EmitByte(0x00, CurByte, OS);
|
||||
EmitRawByte((val >> 24) & 0xFF, CurByte, OS);
|
||||
@@ -155,7 +155,7 @@ EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const {
|
||||
}
|
||||
|
||||
void MBlazeMCCodeEmitter::
|
||||
EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte,
|
||||
EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte,
|
||||
raw_ostream &OS) const {
|
||||
MCOperand mcop = MI.getOperand(op);
|
||||
if (mcop.isExpr()) {
|
||||
@@ -170,11 +170,11 @@ void MBlazeMCCodeEmitter::
|
||||
EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind,
|
||||
unsigned &CurByte, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
assert( MI.getNumOperands()>opNo && "Not enought operands for instruction" );
|
||||
assert(MI.getNumOperands()>opNo && "Not enought operands for instruction");
|
||||
|
||||
MCOperand oper = MI.getOperand(opNo);
|
||||
if (oper.isImm()) {
|
||||
EmitIMM( oper, CurByte, OS );
|
||||
EmitIMM(oper, CurByte, OS);
|
||||
} else if (oper.isExpr()) {
|
||||
Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind));
|
||||
}
|
||||
@@ -198,25 +198,25 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
return;
|
||||
|
||||
case MBlazeII::FRRI:
|
||||
EmitImmediate( MI, 2, FK_Data_4, CurByte, OS, Fixups );
|
||||
EmitImmediate(MI, 2, FK_Data_4, CurByte, OS, Fixups);
|
||||
break;
|
||||
|
||||
case MBlazeII::FRIR:
|
||||
EmitImmediate( MI, 1, FK_Data_4, CurByte, OS, Fixups );
|
||||
EmitImmediate(MI, 1, FK_Data_4, CurByte, OS, Fixups);
|
||||
break;
|
||||
|
||||
case MBlazeII::FCRI:
|
||||
EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS,
|
||||
Fixups );
|
||||
EmitImmediate(MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS,
|
||||
Fixups);
|
||||
break;
|
||||
|
||||
case MBlazeII::FRCI:
|
||||
EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
|
||||
Fixups );
|
||||
EmitImmediate(MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
|
||||
Fixups);
|
||||
|
||||
case MBlazeII::FCCI:
|
||||
EmitImmediate( MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
|
||||
Fixups );
|
||||
EmitImmediate(MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
|
||||
Fixups);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -32,7 +32,7 @@ using namespace llvm;
|
||||
MCSymbol *MBlazeMCInstLower::
|
||||
GetGlobalAddressSymbol(const MachineOperand &MO) const {
|
||||
switch (MO.getTargetFlags()) {
|
||||
default:
|
||||
default:
|
||||
llvm_unreachable("Unknown target flag on GV operand");
|
||||
|
||||
case 0: break;
|
||||
|
@@ -26,11 +26,11 @@ namespace llvm {
|
||||
class MBlazeFunctionInfo : public MachineFunctionInfo {
|
||||
|
||||
private:
|
||||
/// Holds for each function where on the stack the Frame Pointer must be
|
||||
/// Holds for each function where on the stack the Frame Pointer must be
|
||||
/// saved. This is used on Prologue and Epilogue to emit FP save/restore
|
||||
int FPStackOffset;
|
||||
|
||||
/// Holds for each function where on the stack the Return Address must be
|
||||
/// Holds for each function where on the stack the Return Address must be
|
||||
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
|
||||
int RAStackOffset;
|
||||
|
||||
@@ -50,22 +50,22 @@ private:
|
||||
: FI(FrameIndex), SPOffset(StackPointerOffset) {}
|
||||
};
|
||||
|
||||
/// When PIC is used the GP must be saved on the stack on the function
|
||||
/// prologue and must be reloaded from this stack location after every
|
||||
/// call. A reference to its stack location and frame index must be kept
|
||||
/// When PIC is used the GP must be saved on the stack on the function
|
||||
/// prologue and must be reloaded from this stack location after every
|
||||
/// call. A reference to its stack location and frame index must be kept
|
||||
/// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
|
||||
MBlazeFIHolder GPHolder;
|
||||
|
||||
/// On LowerFormalArguments the stack size is unknown, so the Stack
|
||||
/// Pointer Offset calculation of "not in register arguments" must be
|
||||
/// postponed to emitPrologue.
|
||||
/// Pointer Offset calculation of "not in register arguments" must be
|
||||
/// postponed to emitPrologue.
|
||||
SmallVector<MBlazeFIHolder, 16> FnLoadArgs;
|
||||
bool HasLoadArgs;
|
||||
|
||||
// When VarArgs, we must write registers back to caller stack, preserving
|
||||
// on register arguments. Since the stack size is unknown on
|
||||
// When VarArgs, we must write registers back to caller stack, preserving
|
||||
// on register arguments. Since the stack size is unknown on
|
||||
// LowerFormalArguments, the Stack Pointer Offset calculation must be
|
||||
// postponed to emitPrologue.
|
||||
// postponed to emitPrologue.
|
||||
SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs;
|
||||
bool HasStoreVarArgs;
|
||||
|
||||
@@ -83,8 +83,8 @@ private:
|
||||
int VarArgsFrameIndex;
|
||||
|
||||
public:
|
||||
MBlazeFunctionInfo(MachineFunction& MF)
|
||||
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
|
||||
MBlazeFunctionInfo(MachineFunction& MF)
|
||||
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
|
||||
GPHolder(-1,-1), HasLoadArgs(false), HasStoreVarArgs(false),
|
||||
SRetReturnReg(0), GlobalBaseReg(0), VarArgsFrameIndex(0)
|
||||
{}
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; }
|
||||
|
||||
bool hasLoadArgs() const { return HasLoadArgs; }
|
||||
bool hasStoreVarArgs() const { return HasStoreVarArgs; }
|
||||
bool hasStoreVarArgs() const { return HasStoreVarArgs; }
|
||||
|
||||
void recordLoadArgsFI(int FI, int SPOffset) {
|
||||
if (!HasLoadArgs) HasLoadArgs=true;
|
||||
@@ -118,13 +118,13 @@ public:
|
||||
|
||||
void adjustLoadArgsFI(MachineFrameInfo *MFI) const {
|
||||
if (!hasLoadArgs()) return;
|
||||
for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i)
|
||||
MFI->setObjectOffset( FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset );
|
||||
for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i)
|
||||
MFI->setObjectOffset(FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset);
|
||||
}
|
||||
void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const {
|
||||
if (!hasStoreVarArgs()) return;
|
||||
for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i)
|
||||
MFI->setObjectOffset( FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset );
|
||||
if (!hasStoreVarArgs()) return;
|
||||
for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i)
|
||||
MFI->setObjectOffset(FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset);
|
||||
}
|
||||
|
||||
unsigned getSRetReturnReg() const { return SRetReturnReg; }
|
||||
|
@@ -25,8 +25,8 @@ class TargetInstrInfo;
|
||||
class Type;
|
||||
|
||||
namespace MBlaze {
|
||||
/// SubregIndex - The index of various sized subregister classes. Note that
|
||||
/// these indices must be kept in sync with the class indices in the
|
||||
/// SubregIndex - The index of various sized subregister classes. Note that
|
||||
/// these indices must be kept in sync with the class indices in the
|
||||
/// MBlazeRegisterInfo.td file.
|
||||
enum SubregIndex {
|
||||
SUBREG_FPEVEN = 1, SUBREG_FPODD = 2
|
||||
@@ -36,7 +36,7 @@ namespace MBlaze {
|
||||
struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
|
||||
const MBlazeSubtarget &Subtarget;
|
||||
const TargetInstrInfo &TII;
|
||||
|
||||
|
||||
MBlazeRegisterInfo(const MBlazeSubtarget &Subtarget,
|
||||
const TargetInstrInfo &tii);
|
||||
|
||||
@@ -70,7 +70,7 @@ struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
|
||||
|
||||
void emitPrologue(MachineFunction &MF) const;
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||
|
||||
|
||||
/// Debug information queries.
|
||||
unsigned getRARegister() const;
|
||||
unsigned getFrameRegister(const MachineFunction &MF) const;
|
||||
|
@@ -14,7 +14,7 @@ def ALU : FuncUnit;
|
||||
def IMULDIV : FuncUnit;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Itinerary classes used for MBlaze
|
||||
// Instruction Itinerary classes used for MBlaze
|
||||
//===----------------------------------------------------------------------===//
|
||||
def IIAlu : InstrItinClass;
|
||||
def IILoad : InstrItinClass;
|
||||
|
@@ -61,7 +61,7 @@ extern "C" void LLVMInitializeMBlazeTarget() {
|
||||
// Register the MC code emitter
|
||||
TargetRegistry::RegisterCodeEmitter(TheMBlazeTarget,
|
||||
llvm::createMBlazeMCCodeEmitter);
|
||||
|
||||
|
||||
// Register the asm backend
|
||||
TargetRegistry::RegisterAsmBackend(TheMBlazeTarget,
|
||||
createMBlazeAsmBackend);
|
||||
|
@@ -18,10 +18,9 @@ namespace llvm {
|
||||
const MCSection *SmallDataSection;
|
||||
const MCSection *SmallBSSSection;
|
||||
public:
|
||||
|
||||
|
||||
void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
|
||||
|
||||
/// IsGlobalInSmallSection - Return true if this global address should be
|
||||
/// placed into small data/bss section.
|
||||
bool IsGlobalInSmallSection(const GlobalValue *GV,
|
||||
@@ -29,8 +28,8 @@ namespace llvm {
|
||||
SectionKind Kind) const;
|
||||
|
||||
bool IsGlobalInSmallSection(const GlobalValue *GV,
|
||||
const TargetMachine &TM) const;
|
||||
|
||||
const TargetMachine &TM) const;
|
||||
|
||||
const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
|
||||
SectionKind Kind,
|
||||
Mangler *Mang,
|
||||
|
@@ -1,8 +1,5 @@
|
||||
* Writing out ELF files is close to working but the following needs to
|
||||
be examined more closely:
|
||||
- ELF files are written with the wrong E_MACHINE value because
|
||||
ELFObjectWriter::WriteHeader function does not yet support
|
||||
target specific E_MACHINE values.
|
||||
- ELF relocation records are incorrect because the function
|
||||
ELFObjectWriter::RecordRelocation is hard coded for X86/X86-64.
|
||||
- Relocations use 2-byte / 4-byte to terminology in reference to
|
||||
@@ -32,3 +29,11 @@
|
||||
and need to be updated to model the MicroBlaze correctly.
|
||||
- Look at the MBlazeGenFastISel.inc stuff and make use of it
|
||||
if appropriate.
|
||||
|
||||
* A basic assembly parser is present now and seems to parse most things.
|
||||
There are a few things that need to be looked at:
|
||||
- There are some instructions that are not generated by the backend
|
||||
and have not been tested as far as the parser is concerned.
|
||||
- The assembly parser does not use any MicroBlaze specific directives.
|
||||
I should investigate if there are MicroBlaze specific directive and,
|
||||
if there are, add them.
|
||||
|
Reference in New Issue
Block a user