Search code examples
llvmllvm-clang

64 bit immediates in llvm target code generation


I am working on a research project where I am usingllvm to generate some assembly for a custom isa. I am feeding my assembly into a simulator for the time being. Part of my isa allows for 64 bit immediate values in an instruction encoding, I am using a modified version of the sparcv9 target with datalayout: E-m:e-i64:64-n64:64-S128. For some reason when I try to make an instruction for this, I am only getting the lower 32 bits of the value. When I expect to get "enter rd, 4629559679448514560" I instead get "enter, rd, 0" because the lower 32 bits are all 0 in this long.

def ENTER64 : SDNodeXForm<imm, [{
  printf("enter64: N: %lu\n", N->getZExtValue());
  uint64_t Val = N->getZExtValue();
  SDValue temp = CurDAG->getTargetConstant(Val, SDLoc(N),
                                   MVT::i64);
  return temp;
}]>;

def ENTERimm  : PatLeaf<(imm), [{ 
                        printf("enterimm: N: %lu\n", N->getZExtValue()); // debug
                        return true; //  was isInt<64>(N->getSEztValue());
                        }], ENTER64>;
def ENTER: Instruction<
                 (outs I64Regs:$rd), (ins i64imm:$imm),
                 "enter $rd, $imm",
                 [(set i64:$rd, ENTERimm:$imm)],
                 IIC_iu_instr>;

Has anybody here used 64 bit immediates with llvm before and gotten it working? I have been stuck on this for almost 2 weeks now.


Solution

  • Probably the problem is elsewhere and you'd need to check how the immediate is printed down to assembly file? Steps to check:

    1. Check how the SDAG is create
    2. Check how instruction is selected and what is an imm in MI
    3. Check MI=>MC lowering
    4. Check assembly printing.

    PS: You don't need PatLeaf here. Using just imm:$imm should work, there is nothing to check.