[llvm-dev] Unsigned int displaying as negative

Daniel Sanders via llvm-dev llvm-dev at lists.llvm.org
Thu Feb 16 07:23:44 PST 2017


Hi Ryan,

simm16 and uimm16 from the Mips target are primarily about assembly matching and printing rather than instruction selection. They're the same thing to the instruction selector. They're both an 'imm' with the result type limited to i32. For instruction selection, the thing to focus on is immSExt16 and immZExt16 since these determine whether the match is successful or not.

The reason both immSExt16 and immZExt16 exist is that the 32-bit arithmetic operations can only take a sign-extended 16-bit immediate (so -0x8000 is acceptable, but 0x8000 is not). Meanwhile, the 32-bit bitwise operations* can only take a zero-extended 16-bits (0x8000 is acceptable but -0x8000 is not).

*They're actually register-width but that doesn't matter for this topic.

> On 15 Feb 2017, at 20:29, Ryan Taylor via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> I believe that the idea of simm16 and uimm16 was taken over from MipsInstrInfo.td. It's entirely possible that the concepts were misunderstood then.
>  
> So, a broader question, what is the best way to map down to an unsigned/signed sub/add (is this even possible)? How to add signed/unsigned immediates?
> 
> Thanks.
> 
> On Wed, Feb 15, 2017 at 3:14 PM, Friedman, Eli <efriedma at codeaurora.org <mailto:efriedma at codeaurora.org>> wrote:
> On 2/15/2017 11:37 AM, Ryan Taylor via llvm-dev wrote:
> I see. If I put simm16 and immSExt16x in place of uimm16 and immZExt16x respectively, the imm matches but it prints out -32768 (which is invalid for sub16u). We are using uimm16 not match unsigned but for PrintMethod, effectively uimm16 and simm16 are both Operand<i16>. I'm still unclear why simm16 matches and uimm16 does not. Here is the pattern if that helps at all.
> 
> So just as a reference:
> 
> def simm16      : Operand<i16> {
>   let DecoderMethod= "DecodeSimm16";
>   let OperandType = "OPERAND_IMMEDIATE";
> }
> 
> def uimm16      : Operand<i16> {
>   let PrintMethod = "printUnsignedImm";
>   let OperandType = "OPERAND_IMMEDIATE";
> }
> 
> def immSExt16x : ImmLeaf<i16, [{ return isInt<16>(Imm); }]>;
> def immZExt16x : ImmLeaf<i16, [{ return isUInt<16>(Imm); }]>;
> 
> "Imm" in ImmLeaf is an int64_t, sign-extended from your immediate type (in this case, int16_t).  You'd need to insert an explicit cast to uint16_t to get the behavior you want.
> 
> I'm not sure why you're doing this, though; every 16-bit integer immediate fits into a 16-bit integer, so a correctly implemented "immZExt16x" is just equivalent to "imm".
> 
> 
> -Eli
> 
> -- 
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
> 
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170216/67851dac/attachment.html>


More information about the llvm-dev mailing list