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:
Sanjiv Gupta 2008-11-26 10:53:50 +00:00
parent 25a1b47cc3
commit 8f78fa827e
5 changed files with 120 additions and 38 deletions

View File

@ -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

View File

@ -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);

View File

@ -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");

View File

@ -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);

View File

@ -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>: