Skip to content

That’s More Like It!

December 16, 2014

As of my latest changes, the llvm intermediate language file below turns into correct assembly text in a .s file and object code in a .elf file(WOOHOO!).

define i32 @foo(i32 %a, i32 %b) #0 {
    br label %exit
    ret i32 2
	LD2I r0,#2
	SEP 5

x14-12-16 elf
There’s my correct object output. To implement the “load immediate” I had to make a new entry(InstCOSldri) in for a 6 byte “instruction”, an entry(COSLD2I) in to fill it in, and a change to LEGISelDAGToDAG.cpp(in the function SelectMoveImmediate) to use COSLD2I where it had been using MOVLO16i. I also had to change the function EncodeInstruction in LEGMCCodeEmitter.cpp to allow a 6 byte instruction and ALSO, in that same function, I had to change the variable Binary from 4 to 8 bytes to accept a return of >4 bytes from getBinaryCodeForInstr. I also note that getBinaryCodeForInstr returns a uint64_t so there’s a limit of 8 bytes on the size of instructions as it stands. That’s ok, I want to decompose these 1802 instruction strings anyway once I figure out how to do that.

The assembly language text output from llvm is quite independent of the machine code emitter and is also driven by the changes I made. so I got the assembly text for the same work and less fiddling.

The abbreviated diff output follows

+++ b/lib/Target/LEG/
@@ -24,6 +24,25 @@ 
+// 48 bit COSMAC load register immediate instruction
+class InstCOSldri<dag outs, dag ins, string asmstr, list<dag> pattern>
+: Instruction {
+    field bits<48> Inst;
+    let Namespace = "LEG";
+    dag OutOperandList = outs;
+    dag InOperandList = ins;
+    let AsmString   = asmstr;
+    let Pattern = pattern;
+    let Size = 6;
+    // Set dummy values
+    let Inst{47-0} = 0x777777777777;

+++ b/lib/Target/LEG/
+def COSLD2I : InstCOSldri<(outs GRRegs:$dst),(ins i32imm:$imm),"LD2I $dst,$imm",
+                [(set i32:$dst, i32imm_lo:$imm)]>{
+        bits<4> dst;
+        bits<16> imm;
+        let Inst{7-0} =0xf8;
+        let Inst{15-8}  = imm{15-8};
+        let Inst{23-16}=0xB0;
+        let Inst{19-16}=dst;
+        let Inst{31-24} =0xf8;
+        let Inst{39-32} = imm{7-0};
+        let Inst{47-40}=0xB0;
+        let Inst{47-44}=dst;
+def CxSLD2I : MOV<0b1000, "LD2I", (ins i32imm:$imm),
+                  [(set i32:$dst, i32imm_lo:$imm)]>;

+++ b/lib/Target/LEG/LEGISelDAGToDAG.cpp
-      CurDAG->getMachineNode(LEG::MOVLOi16, N, MVT::i32, ConstLo);
+      CurDAG->getMachineNode(LEG::COSLD2I, N, MVT::i32, ConstLo);

+++ b/lib/Target/LEG/MCTargetDesc/LEGMCCodeEmitter.cpp
-  if (Desc.getSize() != 4  and Desc.getSize() != 1) { //wjr
+  if (Desc.getSize() != 6  and Desc.getSize() != 4  and Desc.getSize() != 1) { //wjr
-  const uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
+  const uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); //wjr

That output actually is not correct – the first word is ok but the second word should be 02A0D500 instead of 0200D500


From → LLVM

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: