[LLVMdev] inline asm semantics: output constraint width smaller than input

Török Edwin edwintorok at gmail.com
Tue Jan 27 12:36:36 PST 2009


On 2009-01-27 22:24, Duncan Sands wrote:
> On Tuesday 27 January 2009 20:56:30 Mike Stump wrote:
>   
>> On Jan 27, 2009, at 8:42 PM, Duncan Sands wrote:
>>     
>>> one thing that seems to be clear to everyone except me is... what  
>>> are the
>>> semantics supposed to be?
>>>       
>> I don't know of any other semantic other than, if they are supposed to  
>> be in the same register, then they have to be in the same register.
>>     
>
> Sounds logical!  But what is the discussion about then?

LLVM's Codegen is rejecting inline asm when input/output constraints
have different bitwidths.

For example in the Linux kernel calls to the various __put_user_
functions take %al, %ax, %eax, %rax/ (%eax:%edx) as input parameter,
and the output parameter is always an int (%eax). (hope I explained this
right)

But if I got it right, the input can also be a struct (who's size is 1,
2, 4, 8-byte) that fits in a register.
Not sure if this ever occurs in practice.

#define __put_user_x(size, x, ptr, __ret_pu)            \
    asm volatile("call __put_user_" #size : "=a" (__ret_pu)    \
             :"0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")


#define put_user(x, ptr)                    \
({                                \
    int __ret_pu;                        \
    __typeof__(*(ptr)) __pu_val;                \
    __chk_user_ptr(ptr);                    \
    __pu_val = x;                        \
    switch (sizeof(*(ptr))) {                \
    case 1:                            \
        __put_user_x(1, __pu_val, ptr, __ret_pu);    \
        break;                        \
    case 2:                            \
        __put_user_x(2, __pu_val, ptr, __ret_pu);    \
        break;                        \
    case 4:                            \
        __put_user_x(4, __pu_val, ptr, __ret_pu);    \
        break;                        \
    case 8:                            \
        __put_user_x8(__pu_val, ptr, __ret_pu);        \
        break;                        \
    default:                        \
        __put_user_x(X, __pu_val, ptr, __ret_pu);    \
        break;                        \
    }                            \
    __ret_pu;                        \
})

Best regards,
--Edwin



More information about the llvm-dev mailing list