mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 17:29:19 +00:00
Emit declaration for globals and externs.
Custom lower AND, OR, XOR bitwise operations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60098 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
25a1b47cc3
commit
8f78fa827e
@ -86,7 +86,7 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
O << '\n';
|
||||
}
|
||||
else
|
||||
O << "_" << CurrentFnName << ":\n";
|
||||
O << CurrentFnName << ":\n";
|
||||
CurrentBankselLabelInBasicBlock = "";
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
|
||||
II != E; ++II) {
|
||||
@ -141,15 +141,42 @@ bool PIC16AsmPrinter::doInitialization (Module &M) {
|
||||
// The processor should be passed to llc as in input and the header file
|
||||
// should be generated accordingly.
|
||||
O << "\t#include P16F1937.INC\n";
|
||||
|
||||
EmitExternsAndGlobals (M);
|
||||
EmitInitData (M);
|
||||
EmitUnInitData(M);
|
||||
EmitRomData(M);
|
||||
return Result;
|
||||
}
|
||||
|
||||
void PIC16AsmPrinter::EmitInitData (Module &M)
|
||||
{
|
||||
void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) {
|
||||
// Emit declarations for external functions.
|
||||
O << "section.0" <<"\n";
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
|
||||
std::string Name = Mang->getValueName(I);
|
||||
if (Name.compare("abort") == 0)
|
||||
continue;
|
||||
if (I->isDeclaration()) {
|
||||
O << "\textern " <<Name << "\n";
|
||||
O << "\textern " << Name << ".retval\n";
|
||||
O << "\textern " << Name << ".args\n";
|
||||
}
|
||||
else if (I->hasExternalLinkage()) {
|
||||
O << "\tglobal " << Name << "\n";
|
||||
O << "\tglobal " << Name << ".retval\n";
|
||||
O << "\tglobal " << Name << ".args\n";
|
||||
}
|
||||
}
|
||||
// Emit declarations for external globals.
|
||||
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; I++) {
|
||||
std::string Name = Mang->getValueName(I);
|
||||
if (I->isDeclaration())
|
||||
O << "\textern "<< Name << "\n";
|
||||
else if (I->getLinkage() == GlobalValue::CommonLinkage)
|
||||
O << "\tglobal "<< Name << "\n";
|
||||
}
|
||||
}
|
||||
void PIC16AsmPrinter::EmitInitData (Module &M) {
|
||||
std::string iDataSection = "idata.#";
|
||||
SwitchToDataSection(iDataSection.c_str());
|
||||
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
|
||||
@ -295,16 +322,26 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
||||
O << "\n";
|
||||
std::string fDataSection = "fdata." + CurrentFnName + ".#";
|
||||
SwitchToUDataSection(fDataSection.c_str(), F);
|
||||
// Emit the label for data section of current function.
|
||||
O << "_frame_" << CurrentFnName << ":" ;
|
||||
O << "\n";
|
||||
|
||||
//Emit function return value.
|
||||
O << CurrentFnName << ".retval:\n";
|
||||
const Type *RetType = F->getReturnType();
|
||||
if (RetType->getTypeID() != Type::VoidTyID) {
|
||||
unsigned RetSize = TD->getABITypeSize(RetType);
|
||||
if (RetSize > 0)
|
||||
O << CurrentFnName << ".retval" << " RES " << RetSize;
|
||||
}
|
||||
// Emit function arguments.
|
||||
O << CurrentFnName << ".args:\n";
|
||||
for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
|
||||
AI != AE; ++AI) {
|
||||
std::string ArgName = Mang->getValueName(AI);
|
||||
const Type *ArgTy = AI->getType();
|
||||
unsigned ArgSize = TD->getABITypeSize(ArgTy);
|
||||
O << CurrentFnName << ".args." << ArgName << " RES " << ArgSize;
|
||||
}
|
||||
// Emit the function variables.
|
||||
|
||||
if (F->hasExternalLinkage()) {
|
||||
O << "\t" << "GLOBAL _frame_" << CurrentFnName << "\n";
|
||||
O << "\t" << "GLOBAL _" << CurrentFnName << "\n";
|
||||
}
|
||||
// In PIC16 all the function arguments and local variables are global.
|
||||
// Therefore to get the variable belonging to this function entire
|
||||
// global list will be traversed and variables belonging to this function
|
||||
|
@ -42,6 +42,7 @@ namespace llvm {
|
||||
const GlobalValue *GV = NULL);
|
||||
bool printInstruction(const MachineInstr *MI); // definition autogenerated.
|
||||
bool printMachineInstruction(const MachineInstr *MI);
|
||||
void EmitExternsAndGlobals (Module &M);
|
||||
void EmitInitData (Module &M);
|
||||
void EmitUnInitData (Module &M);
|
||||
void EmitRomData (Module &M);
|
||||
|
@ -55,6 +55,10 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
|
||||
setOperationAction(ISD::ADD, MVT::i8, Legal);
|
||||
setOperationAction(ISD::ADD, MVT::i16, Custom);
|
||||
|
||||
setOperationAction(ISD::OR, MVT::i8, Custom);
|
||||
setOperationAction(ISD::AND, MVT::i8, Custom);
|
||||
setOperationAction(ISD::XOR, MVT::i8, Custom);
|
||||
|
||||
setOperationAction(ISD::SHL, MVT::i16, Custom);
|
||||
setOperationAction(ISD::SHL, MVT::i32, Custom);
|
||||
|
||||
@ -532,6 +536,10 @@ SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo());
|
||||
case ISD::SHL:
|
||||
return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo());
|
||||
case ISD::OR:
|
||||
case ISD::AND:
|
||||
case ISD::XOR:
|
||||
return LowerBinOp(Op, DAG);
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
@ -570,6 +578,21 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
|
||||
return Load.getValue(0);
|
||||
}
|
||||
|
||||
SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
|
||||
// We should have handled larger operands in type legalizer itself.
|
||||
assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
|
||||
|
||||
// Return the original Op if the one of the operands is already a load.
|
||||
if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
|
||||
|| Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
|
||||
return Op;
|
||||
|
||||
// Put one value on stack.
|
||||
SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
|
||||
|
||||
return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(0), NewVal);
|
||||
}
|
||||
|
||||
SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) {
|
||||
// We should have handled larger operands in type legalizer itself.
|
||||
assert (Op.getValueType() == MVT::i8 && "illegal addc to lower");
|
||||
|
@ -64,6 +64,7 @@ namespace llvm {
|
||||
SDValue LowerADDC(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerSUBE(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerSUBC(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG);
|
||||
|
||||
SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG);
|
||||
SDNode *ExpandStore(SDNode *N, SelectionDAG &DAG);
|
||||
|
@ -75,17 +75,44 @@ def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>;
|
||||
// Node to match a direct load operation.
|
||||
def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
|
||||
|
||||
// Nodes to match bitwise operatios.
|
||||
def OR : SDNode<"ISD::OR", SDTI8BinOp>;
|
||||
def XOR : SDNode<"ISD::XOR", SDTI8BinOp>;
|
||||
def AND : SDNode<"ISD::AND", SDTI8BinOp>;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PIC16 Operand Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
def i8mem : Operand<i8>;
|
||||
|
||||
include "PIC16InstrFormats.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PIC16 Common Classes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// W = W Op F : Load the value from F and do Op to W
|
||||
class BinOpFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
|
||||
ByteFormat<OpCode, (outs GPR:$dst),
|
||||
(ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
|
||||
!strconcat(OpcStr, " $ptrlo + $offset, W"),
|
||||
[(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
|
||||
(i8 imm:$ptrhi),
|
||||
(i8 imm:$offset))))]>;
|
||||
// F = F Op W : Load the value from F, do op with W and store in F
|
||||
class BinOpWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
|
||||
ByteFormat<OpCode, (outs),
|
||||
(ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
|
||||
!strconcat(OpcStr, " $ptrlo + $offset"),
|
||||
[(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
|
||||
(i8 imm:$ptrhi),
|
||||
(i8 imm:$offset))),
|
||||
diraddr:$ptrlo,
|
||||
(i8 imm:$ptrhi), (i8 imm:$offset)
|
||||
)]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PIC16 Instructions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
include "PIC16InstrFormats.td"
|
||||
|
||||
// Pseudo-instructions.
|
||||
def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
|
||||
@ -188,37 +215,30 @@ def load_indirect :
|
||||
"moviw $offset[$fsr]",
|
||||
[]>;
|
||||
|
||||
//-------------------------
|
||||
// Bitwise operations patterns
|
||||
//--------------------------
|
||||
def OrFW : BinOpFW<0, "iorwf", OR>;
|
||||
def XOrFW : BinOpFW<0, "xorwf", XOR>;
|
||||
def AndFW : BinOpFW<0, "andwf", AND>;
|
||||
|
||||
def OrWF : BinOpWF<0, "iorwf", OR>;
|
||||
def XOrWF : BinOpWF<0, "xorwf", XOR>;
|
||||
def AndWF : BinOpWF<0, "andwf", AND>;
|
||||
|
||||
//-------------------------
|
||||
// Various add/sub patterns.
|
||||
//-------------------------
|
||||
// W += [F] ; load from F and add the value to W.
|
||||
class ADDFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
|
||||
ByteFormat<OpCode, (outs GPR:$dst),
|
||||
(ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
|
||||
!strconcat(OpcStr, " $ptrlo + $offset, W"),
|
||||
[(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
|
||||
(i8 imm:$ptrhi),
|
||||
(i8 imm:$offset))))]>;
|
||||
|
||||
// let isTwoAddress = 1 in {
|
||||
def addfw_1: ADDFW<0, "addwf", add>;
|
||||
def addfw_2: ADDFW<0, "addwf", addc>;
|
||||
def addfwc: ADDFW<0, "addwfc", adde>; // With Carry.
|
||||
def addfw_1: BinOpFW<0, "addwf", add>;
|
||||
def addfw_2: BinOpFW<0, "addwf", addc>;
|
||||
def addfwc: BinOpFW<0, "addwfc", adde>; // With Carry.
|
||||
// }
|
||||
|
||||
// [F] += W ; add the value of W to [F].
|
||||
class ADDWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
|
||||
ByteFormat<OpCode, (outs),
|
||||
(ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
|
||||
!strconcat(OpcStr, " $ptrlo + $offset"),
|
||||
[(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
|
||||
(i8 imm:$ptrhi),
|
||||
(i8 imm:$offset))),
|
||||
diraddr:$ptrlo,
|
||||
(i8 imm:$ptrhi), (i8 imm:$offset)
|
||||
)]>;
|
||||
def addwf_1: ADDWF<0, "addwf", add>;
|
||||
def addwf_2: ADDWF<0, "addwf", addc>;
|
||||
def addwfc: ADDWF<0, "addwfc", adde>; // With Carry.
|
||||
def addwf_1: BinOpWF<0, "addwf", add>;
|
||||
def addwf_2: BinOpWF<0, "addwf", addc>;
|
||||
def addwfc: BinOpWF<0, "addwfc", adde>; // With Carry.
|
||||
|
||||
// W -= [F] ; load from F and sub the value from W.
|
||||
class SUBFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
|
||||
|
Loading…
Reference in New Issue
Block a user