From 8f78fa827ec4732b3c39cfd4b73c36829616b105 Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Wed, 26 Nov 2008 10:53:50 +0000 Subject: [PATCH] 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 --- lib/Target/PIC16/PIC16AsmPrinter.cpp | 61 +++++++++++++++++----- lib/Target/PIC16/PIC16AsmPrinter.h | 1 + lib/Target/PIC16/PIC16ISelLowering.cpp | 23 ++++++++ lib/Target/PIC16/PIC16ISelLowering.h | 1 + lib/Target/PIC16/PIC16InstrInfo.td | 72 ++++++++++++++++---------- 5 files changed, 120 insertions(+), 38 deletions(-) diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index 21f1902a9ec..6bb3b5d26f1 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -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 " <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 diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h index a2b501c8cf4..b0a2baf1fc3 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.h +++ b/lib/Target/PIC16/PIC16AsmPrinter.h @@ -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); diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index feb21ef54df..c085da9a750 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -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"); diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index dfe5b5f7e45..a2af24c6d90 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -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); diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td index 0335e92bbf9..60d92ecc369 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.td +++ b/lib/Target/PIC16/PIC16InstrInfo.td @@ -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; +include "PIC16InstrFormats.td" +//===----------------------------------------------------------------------===// +// PIC16 Common Classes. +//===----------------------------------------------------------------------===// + +// W = W Op F : Load the value from F and do Op to W +class BinOpFW OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; +// F = F Op W : Load the value from F, do op with W and store in F +class BinOpWF OpCode, string OpcStr, SDNode OpNode>: + ByteFormat; //===----------------------------------------------------------------------===// // 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 OpCode, string OpcStr, SDNode OpNode>: - ByteFormat; + // 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 OpCode, string OpcStr, SDNode OpNode>: - ByteFormat; -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 OpCode, string OpcStr, SDNode OpNode>: