2015-11-01 3 views
1

Я пытаюсь запустить код сборки для моей собственной пользовательской инструкции.Как передать целое число в качестве входного параметра в пользовательской инструкции asm?

код, как показано ниже

#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); 
} 

} 

поэтому в основном инструкции custom0, как показано выше, работает, как, как показано ниже.

//    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 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 

Как вы можете видеть значение я правильно, но величина г всегда равна нулю.

набор инструкций используется является RISCV ISA: - http://riscv.org/download.html#tab_spec_user_isa

+0

Я также попытался использовать базовую Int. didnt work –

+0

Какой у вас компилятор? Вы должны проверить раздел «Ограничения для операндов asm» компилятора вашей арки (основные ограничения для gcc находятся здесь - https://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Simple-Constraints.html#Simple -Constraints) Я не уверен, что поле «address» будет иметь ограничение «r». Также вы можете проверить выход asm вашего компилятора (с параметром -S) и ассемблером. – osgx

+0

Я использую riscv newlib компилятор на основе GCC 4.8 –

ответ

1

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

Как я понимаю, @custom0 инструкция (https://github.com/riscv/riscv-opcodes/blob/master/opcodes-custom) получают только 2 регистры в качестве первого и второго аргумента; Третий аргумент - «imm12» = немедленный. Таким образом, есть способ для ассемблера кодировать регистр x0 и% 0 (который будет регистрироваться), но поле imm должно иметь «i» (немедленное) ограничение, а не «r» (регистр) - проверить gcc doc на ограничения: https://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Simple-Constraints.html#Simple-Constraints

Немедленное поле должно быть закодировано в команде ассемблером, оно является частью командного двоичного кодирования. У вас нет никакого юридического варианта для кодирования переменной времени выполнения внутри двоичного кода вашей программы, поэтому вы не можете передать int i как "i" аргумент asm. "i" аргумент принимает только константы времени компиляции.

Вы можете переписать код в виде 4 ассемблера заявления без петли с «я» и постоянным значением

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));