<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none"><!--P{margin-top:0;margin-bottom:0;} p
        {margin-top:0;
        margin-bottom:0}--></style>
</head>
<body dir="ltr" style="font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;">
<p>Hallo,</p>
<p><br>
</p>
<p>I am trying to build a backend for a simple 16-bit CPU with a very small instruction set of only 24 instructions called PROL16 is used to teach CPU architecture and chip design.
<br>
</p>
<p><br>
</p>
<p>I am using Fraser Cormack and Pierre-Andre Saulais LEG CPU (<a title="Ctrl+Klicken oder tippen Sie, um dem Link zu folgen." href="https://github.com/frasercrmck/llvm-leg">https://github.com/frasercrmck/llvm-leg</a>) as starting point.<br>
</p>
<p><br>
</p>
<p>I do struggle with the concept of indirect loads and jumps where the address to jump has to be save in an register first.</p>
<p><br>
</p>
<p>So my jump looks like this:</p>
<p>jump r3</p>
<p>where register r3 is containing the address to jump to.</p>
<p><br>
</p>
<p>When I change the  InstrInfo.td from a direct jump like this:<br>
</p>
<br>
<p>let isTerminator = 1, isBranch = 1, isBarrier = 1 in {<br>
  def B : InstLEG<(outs), (ins b_target:$dst),<br>
                  "b $dst", [(br bb:$dst)]> {<br>
    bits<24> dst;<br>
    let Inst{31-28} = 0b0000;<br>
    let Inst{27-24} = 0b1010;<br>
    let Inst{23-0} = dst;<br>
  }<br>
} </p>
<p><br>
</p>
<p>to register based like:</p>
<p><br>
</p>
<p>def SDT_LEGJmpLink      : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;<br>
def LEGJmpLink : SDNode<"LEG::B",SDT_LEGJmpLink,<br>
                         [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,<br>
                          SDNPVariadic]>;<br>
<br>
let isTerminator = 1, isBranch = 1, isBarrier = 1 in {<br>
  def B : InstLEG<(outs), (ins GRRegs:$Ra, variable_ops),<br>
                  "JUMP", [(LEGJmpLink  GRRegs:$Ra)]> {<br>
    bits<24> dst;<br>
    let Inst{31-28} = 0b0000;<br>
    let Inst{27-24} = 0b1010;<br>
    //let Inst{23-0} = dst;<br>
  }<br>
}<br>
<br>
def : Pat<(LEGJmpLink (i32 tglobaladdr:$dst)),<br>
          (B tglobaladdr:$dst)>;<br>
def : Pat<(LEGJmpLink (i32 texternalsym:$dst)),<br>
          (B texternalsym:$dst)>;<br>
</p>
<p><br>
</p>
<p>This is used in CPU0, MIPS and LEG for call.</p>
<p><br>
</p>
<p>When I translate my test IR code LLVM is unable to match the Branch.</p>
<p><br>
</p>
<p>LLVM ERROR: Cannot select: 0x9f32948: ch = br 0x9f32504, 0x9f328ac [ORD=13] [ID=20]<br>
In function: _Z17test_add_overflowv</p>
<p><br>
</p>
<p>I clearly do not understand how the concept for loading an address to a register works in LLVM.</p>
<p><br>
</p>
<p>For some insights I would be very thankful.</p>
<p><br>
</p>
<p>BR</p>
<p>Georg<br>
</p>
</body>
</html>