Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an integer as input parameter in asm custom instruction in?

I am trying to run an assembly code for my own custom instruction.

The code is as below

#include <assert.h>
#include <stdio.h>
#include <stdint.h>


int main() {
  uint64_t x = 123, y = 456, z = 0, a=22;
  int i;

for(i=0;i<4;i++)
{
  asm volatile ("custom0 x0, %0, %[i], 0" : : "r"(i),[i]"r"(i));
  printf("The value of i is:- %d \n",i);
  asm volatile ("custom0 %0, x0, %[i], 1" : "=r"(z) :[i]"r"(i));
  printf("The value of z %d is:- %d \n",i,z);
}

}

So basically the custom0 instruction as shown above works like as shown below.

//             opcode
//             |               address
//             |               |
//             |               |       
asm volatile ("custom0 x0, %0, 1, 0" : : "r"(i));//for moving i to address 1
asm volatile ("custom0 %0, x0, 1, 1" : "=r"(z));//for moving contents of address 1 to z.

The instruction works fine standalone, but when i try to parameterise the address field and run in a for loop the data is not moved into that address.

the output of the above program is

The value of i is:- 0 
The value of z 0 is:- 0 
The value of i is:- 1 
The value of z 1 is:- 0 
The value of i is:- 2 
The value of z 2 is:- 0 
The value of i is:- 3 
The value of z 3 is:- 0 

As you can see the value of i is correct but the value of z is always zero.

Instruction set being used is the RISCV ISA:- http://riscv.org/download.html#tab_spec_user_isa

like image 480
Prashant Ravi Avatar asked Nov 20 '25 18:11

Prashant Ravi


1 Answers

asm volatile ("custom0 x0, %0, %[i], 0" : : "r"(i),[i]"r"(i));

As I understand, @custom0 instruction (https://github.com/riscv/riscv-opcodes/blob/master/opcodes-custom) get only 2 registers as first and second argument; third argument is "imm12" = immediate. So, there is a way to assembler to encode x0 register and %0 (which will be register), but imm field should have "i" (immediate) constraint, not "r" (register) - check gcc doc on constraints: https://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Simple-Constraints.html#Simple-Constraints

Immediate field should be encoded into the command by assembler, it is part of command binary encoding. You have no any legal variant to encode runtime variable inside the binary code of your program, so you can't pass int i as "i" asm argument. "i" argument accepts only compile-time constants.

You may rewrite code as 4 asm statements without loop with "i" and constant value

asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(0));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(1));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(2));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(3));
like image 65
osgx Avatar answered Nov 22 '25 19:11

osgx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!