O << '\n';
}
else
- O << "_" << CurrentFnName << ":\n";
+ O << CurrentFnName << ":\n";
CurrentBankselLabelInBasicBlock = "";
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// 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();
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
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);
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();
}
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");
// 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),
[]>;
//-------------------------
+// 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>: