Skip to content

Commit fc6626f

Browse files
committed
Support Inline assembly
Chapter 10.2
1 parent b41507b commit fc6626f

File tree

9 files changed

+467
-2
lines changed

9 files changed

+467
-2
lines changed

llvm/lib/Target/Cpu0/Cpu0AsmPrinter.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,136 @@ void Cpu0AsmPrinter::PrinterDebugValueComment(const MachineInstr *MI,
283283
// Opcode == Cpu0::LONG_BRANCH_ADDiu);
284284
// }
285285
//
286+
287+
// Print out an operand for an inline asm expression
288+
bool Cpu0AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
289+
unsigned AsmVariant, const char *ExtraCode,
290+
raw_ostream &O) {
291+
// Asm operand only have single letter modifier
292+
if (ExtraCode && ExtraCode[0]) {
293+
if (ExtraCode[1] != 0) return true; // Unknown modifier
294+
295+
const MachineOperand &MO = MI->getOperand(OpNum);
296+
switch (ExtraCode[0]) {
297+
default:
298+
// See if this is a generic print operand
299+
return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
300+
case 'X': // hex const int
301+
if ((MO.getType()) != MachineOperand::MO_Immediate)
302+
return true;
303+
O << "0x" << StringRef(utohexstr(MO.getImm())).lower();
304+
return false;
305+
case 'x': // hex const int (low 16 bits)
306+
if ((MO.getType()) != MachineOperand::MO_Immediate)
307+
return true;
308+
O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower();
309+
return false;
310+
case 'd': // decimal const int
311+
if ((MO.getType()) != MachineOperand::MO_Immediate)
312+
return true;
313+
O << MO.getImm();
314+
return false;
315+
case 'm': // decimal const int minus 1
316+
if ((MO.getType()) != MachineOperand::MO_Immediate)
317+
return true;
318+
O << MO.getImm() - 1;
319+
return false;
320+
case 'z': {
321+
// $0 if zero, regular printing otherwise
322+
if (MO.getType() != MachineOperand::MO_Immediate)
323+
return true;
324+
int64_t Val = MO.getImm();
325+
if (Val)
326+
O << Val;
327+
else
328+
O << "$0";
329+
return false;
330+
}
331+
}
332+
}
333+
334+
printOperand(MI, OpNum, O);
335+
return false;
336+
}
337+
338+
bool Cpu0AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
339+
unsigned OpNum, unsigned AsmVariant,
340+
const char *ExtraCode,
341+
raw_ostream &O) {
342+
int Offset = 0;
343+
// Currently we are expecting either no ExtraCode or 'D'
344+
if (ExtraCode) {
345+
return true; // Unknown modifier
346+
}
347+
348+
const MachineOperand &MO = MI->getOperand(OpNum);
349+
assert(MO.isReg() && "unexpected inline asm memory operand");
350+
O << Offset << "($" << Cpu0InstPrinter::getRegisterName(MO.getReg()) << ")";
351+
352+
return false;
353+
}
354+
355+
void Cpu0AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
356+
raw_ostream &O) {
357+
const MachineOperand &MO = MI->getOperand(OpNum);
358+
359+
switch (MO.getTargetFlags()) {
360+
case Cpu0II::MO_GPREL: O << "%gp_rel("; break;
361+
case Cpu0II::MO_GOT_CALL: O << "%call16("; break;
362+
case Cpu0II::MO_GOT: O << "%got("; break;
363+
case Cpu0II::MO_ABS_HI: O << "%hi("; break;
364+
case Cpu0II::MO_ABS_LO: O << "%lo("; break;
365+
case Cpu0II::MO_GOT_HI16: O << "got_hi16("; break;
366+
case Cpu0II::MO_GOT_LO16: O << "got_lo16("; break;
367+
}
368+
369+
switch (MO.getType()) {
370+
case MachineOperand::MO_Register:
371+
O << '$' << StringRef(Cpu0InstPrinter::getRegisterName(MO.getReg())).lower();
372+
break;
373+
374+
case MachineOperand::MO_Immediate:
375+
O << MO.getImm();
376+
break;
377+
378+
case MachineOperand::MO_MachineBasicBlock:
379+
O << *MO.getMBB()->getSymbol();
380+
return;
381+
382+
case MachineOperand::MO_GlobalAddress:
383+
O << *getSymbol(MO.getGlobal());
384+
break;
385+
386+
case MachineOperand::MO_BlockAddress: {
387+
MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
388+
O << BA->getName();
389+
break;
390+
}
391+
392+
case MachineOperand::MO_ExternalSymbol:
393+
O << *GetExternalSymbolSymbol(MO.getSymbolName());
394+
break;
395+
396+
case MachineOperand::MO_JumpTableIndex:
397+
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
398+
<< '_' << MO.getIndex();
399+
break;
400+
401+
case MachineOperand::MO_ConstantPoolIndex:
402+
O << MAI->getPrivateGlobalPrefix() << "CPI"
403+
<< getFunctionNumber() << "_" << MO.getIndex();
404+
if (MO.getOffset())
405+
O << "+" << MO.getOffset();
406+
break;
407+
408+
default:
409+
llvm_unreachable("<unknown operand type>");
410+
}
411+
412+
if (MO.getTargetFlags())
413+
O << ")";
414+
}
415+
286416
// Force static initialization.
287417
extern "C" void LLVMInitializeCpu0AsmPrinter() {
288418
RegisterAsmPrinter<Cpu0AsmPrinter> X(getTheCpu0Target());

llvm/lib/Target/Cpu0/Cpu0AsmPrinter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ class LLVM_LIBRARY_VISIBILITY Cpu0AsmPrinter : public AsmPrinter {
7474
void EmitStartOfAsmFile(Module &M) override;
7575
void PrinterDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
7676

77+
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
78+
unsigned AsmVariant, const char *ExtraCode,
79+
raw_ostream &O) override;
80+
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
81+
unsigned AsmVariant, const char *ExtraCode,
82+
raw_ostream &O) override;
83+
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
84+
7785
};
7886
} // end namespace llvm
7987

llvm/lib/Target/Cpu0/Cpu0ISelDAGToDAG.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,19 @@ SDNode *Cpu0DAGToDAGISel::getGlobalBaseReg() {
157157
CurDAG->getDataLayout()))
158158
.getNode();
159159
}
160+
161+
// Inlineasm
162+
bool Cpu0DAGToDAGISel::
163+
SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
164+
std::vector<SDValue> &OutOps) {
165+
// All memory constraints can at least accept raw pointers
166+
switch (ConstraintID) {
167+
default:
168+
llvm_unreachable("Unexpected asm memory constraint");
169+
case InlineAsm::Constraint_m:
170+
OutOps.push_back(Op);
171+
return false;
172+
}
173+
174+
return true;
175+
}

llvm/lib/Target/Cpu0/Cpu0ISelDAGToDAG.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class Cpu0DAGToDAGISel : public SelectionDAGISel {
6161
// Complex Pattern
6262
bool SelectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Offset);
6363

64+
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
65+
std::vector<SDValue> &OutOps) override;
6466
// Return a target constant with the specified value.
6567
inline SDValue getImm(const SDNode *Node, unsigned Imm) {
6668
return CurDAG->getTargetConstant(Imm, SDLoc(Node), Node->getValueType(0));
@@ -72,4 +74,4 @@ class Cpu0DAGToDAGISel : public SelectionDAGISel {
7274

7375
} // end of llvm namespace
7476

75-
#endif
77+
#endif

0 commit comments

Comments
 (0)