{"id":5347,"date":"2025-02-07T12:21:44","date_gmt":"2025-02-07T11:21:44","guid":{"rendered":"https:\/\/www.islandwalking.com\/wordpress\/?p=5347"},"modified":"2025-02-07T15:07:31","modified_gmt":"2025-02-07T14:07:31","slug":"llvm-exercise-v","status":"publish","type":"post","link":"https:\/\/www.islandwalking.com\/wordpress\/llvm-exercise-v\/","title":{"rendered":"LLVM Exercise V"},"content":{"rendered":"<p>Let us add some local variables:<\/p>\n<blockquote>\n<pre>int foo() {\r\n  int retval = 0x0AB;\r\n  int dummy = 0;\r\n  return retval;\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>This requires adding some information about accessing memory. I will just postulate that I have memory available from address 1 growing upwards. As anyone that really knows the HP-41 understands, this is a very bad idea. However we are still just showing some basic LLVM principles, not producing actually useful Nut code. I am however excluding the possibility of generating <code>READ 0<\/code>, as that instruction does not even exist.<\/p>\n<p>Some code snippets:<\/p>\n<blockquote>\n<pre>    \/\/ Addressing modes.\r\n    def ADDR : ComplexPattern&lt;iPTR, 2, \"SelectADDR\",\r\n                              [frameindex], []&gt;;\r\n\r\n    \/\/ Address operands\r\n    def MEM : Operand {\r\n      let MIOperandInfo = (ops RC, i16imm);\r\n      let PrintMethod = \"printMemOperand\";\r\n      let DecoderMethod = \"decodeMemOperand\";\r\n    }\r\n    \r\n    ...\r\n    \r\n    let mayLoad=1 in {\r\n    def READ : HP41MCODEInst&lt;0x078, (outs RC:$r),\r\n            (ins MEM:$addr), \"READ $addr\",\r\n            [(set RC:$r, (load ADDR:$addr))]&gt;;\r\n    }\r\n\r\n    let mayStore=1 in {\r\n    def WRIT : HP41MCODEInst&lt;0x068, (outs), (ins MEM:$addr,\r\n            RC:$r), \"WRIT $addr\", [(store RC:$r, ADDR:$addr)]&gt;;\r\n    }\r\n\r\n    ...\r\n\r\n    bool\r\n    HP41MCODERegisterInfo::eliminateFrameIndex(\r\n            MachineBasicBlock::iterator II,\r\n            int SPAdj, unsigned FIOperandNum,\r\n            RegScavenger *RS) const {\r\n        MachineInstr &amp;MI = *II;\r\n        int FrameIndex = MI.getOperand(FIOperandNum).getIndex();\r\n        MachineFunction &amp;MF = *MI.getParent()-&gt;getParent();\r\n        const HP41MCODEFrameLowering *TFI = getFrameLowering(MF);\r\n        llvm::Register FrameReg;\r\n        int Offset;\r\n        Offset = TFI-&gt;getFrameIndexReference(MF, FrameIndex,\r\n                FrameReg).getFixed()\/4+1;\r\n        MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg,\r\n                false);\r\n        MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);\r\n        return false;\r\n    }\r\n\r\n    ...\r\n\r\n    void HP41MCODEInstPrinter::printMemOperand(const MCInst *MI,\r\n            int opNum,\r\n            const MCSubtargetInfo &amp;STI,\r\n            raw_ostream &amp;O, const char *Modifier) {\r\n        const MCOperand &amp;MO = MI-&gt;getOperand(opNum+1);\r\n        \r\n        if (MO.isImm()) {\r\n            O &lt;&lt; format_decimal((int)MO.getImm(), 1); return; }\r\n                    assert(MO.isExpr() &amp;&amp;\r\n                    \"Unknown operand kind in printMemOperand\");\r\n                    MO.getExpr()-&gt;print(O, &amp;MAI);\r\n    }\r\n\r\n    ...\r\n\r\n    bool HP41MCODEDAGToDAGISel::SelectADDR(SDValue Addr,\r\n            SDValue &amp;Base, SDValue &amp;Offset) {\r\n      if (FrameIndexSDNode *FIN = dyn_cast(Addr)) {\r\n        Base = CurDAG-&gt;getTargetFrameIndex(\r\n                FIN-&gt;getIndex(), TLI-&gt;getPointerTy(\r\n                        CurDAG-&gt;getDataLayout()));\r\n        Offset = CurDAG-&gt;getTargetConstant(0, SDLoc(Addr),\r\n                        MVT::i32);\r\n        return true;\r\n      }\r\n\r\n      return false;\r\n    }\r\n\r\n\r\n<\/pre>\n<\/blockquote>\n<p>Then we end up with:<\/p>\n<blockquote>\n<pre>\t.file\t\"hello.c\"\r\n\t.text\r\n\t.globl\tfoo                     ! -- Begin function foo\r\n\t.type\tfoo,@function\r\nfoo:                                    ! @foo\r\n! %bb.0:                                ! %entry\r\n\tLDI S&amp;X HEX: 0AB\r\n\tWRIT 2\r\n\tC=0 ALL\r\n\tWRIT 1\r\n\tREAD 2\r\n\tRTN\r\n.Lfunc_end0:\r\n\t.size\tfoo, .Lfunc_end0-foo\r\n                                        ! -- End function\r\n\t.ident\t\"clang version 20.0.0git (https:\/\/github.com\/llvm\/llvm-project.git ea1dfd50bfdfbd75969fd7653bc71c81f2a2350f)\"\r\n\t.section\t\".note.GNU-stack\"\r\n\t.addrsig\r\n\r\n<\/pre>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Let us add some local variables: int foo() { int retval = 0x0AB; int dummy = 0; return retval; } This requires adding some information about accessing memory. I will just postulate that I have memory available from address 1 growing upwards. As anyone that really knows the HP-41 understands, this is a very bad &hellip; <a class=\"read-excerpt\" href=\"https:\/\/www.islandwalking.com\/wordpress\/llvm-exercise-v\/\">Continue reading <span class=\"meta-nav\">&raquo;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5347","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/posts\/5347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/comments?post=5347"}],"version-history":[{"count":6,"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/posts\/5347\/revisions"}],"predecessor-version":[{"id":5354,"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/posts\/5347\/revisions\/5354"}],"wp:attachment":[{"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/media?parent=5347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/categories?post=5347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.islandwalking.com\/wordpress\/wp-json\/wp\/v2\/tags?post=5347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}