0
votes

In the RISC-V mannual for this instructions is written:

C.LUI loads the non-zero 6-bit immediate field into bits 17–12 of the destination register, clearsthe bottom 12 bits, and sign-extends bit 17 into all higher bits of the destination

And from this I made the conclusion that the immediate should be 6 bits, but then I was compiling something and this line can be compiled but the immediate is more than 6 bits wide, so I am confused c.lui x14,0xffff8

1
Well, it says that the operand is sign-extended, so maybe the assembler accepts any partially sign-extended variant (e.g. in addition to 0x38 it also accepts 0x78, 0xF8, 0x1F8, etc).Michael
Check what you get from disassembling the result of assembling that. A good assembler should warn about truncating a value to fit in a limited size immediate, but might silently truncate. Also, usually you give the assembler the value you really want, and it handles the encoding. This has some bits set below bit 12 so that's weird.Peter Cordes
@PeterCordes If this is like MIPS's lui, then you specify the value you want for the upper bits, not the value you want for the entire register.Michael
@Michael: Good point, it can be a value to be implicitly left-shifted, forgot how LUI syntax worked. But in general assemblers take values, not raw encodings, so I'm skeptical about "partially sign extended" values; those likely would give a warning or error about truncating or not encodeable. In general, assembling, then looking at the machine code and disassembly is a good way to find out what means what in asm syntax, and to find the canonical syntax for an instruction.Peter Cordes

1 Answers

5
votes

c.lui will accept any 20 bits immediate as long as all the bits 5 to 19 have the same value ( 1 or 0).
So basically c.lui will accept any value between 0xfffe0 and 0xfffff and any value between 1 and 0x1f. 0x0 is not accepted also (see https://riscv.org//wp-content/uploads/2017/05/riscv-spec-v2.2.pdf)

With your example
c.lui a4, 0xffff8 will give the instruction 0x7761 The immediate extracted from this instruction is 0x38 if you shift it by 12 you will get 0x38000 and after that when you sign extend it you will get: 0xffff8000