Operating System - HP-UX
1827245 Members
2211 Online
109716 Solutions
New Discussion

Re: how to call a function by aCC inline assembly

 
SOLVED
Go to solution
jufengyao
Advisor

how to call a function by aCC inline assembly

Hi,

 

I want to call a function by aCC inline assembly, but can't find a pseudo-function which can let me to make a call (some thing like _Asm_call).

any suggestions will be great help!

 

thanks.

25 REPLIES 25
jufengyao
Advisor

Re: how to call a function by aCC inline assembly

if any one can give out a sample code of call a function by aCC inline assembly of IA64, it will be more better: include push parameters, call, and return.

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>I want to call a function by aCC inline assembly,

 

You can't and there is no need to do so.  You do a normal call and intersperse your inline assembly _Asm_ calls.

You might want to explain what you are trying to do?

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

Hi Dennis,

 

thanks for your reply. I need to implement a call function interface. the method define is: 

void* callfunction(int *data, int* type, int count, void* function_address). data: this array contains the parameters which will be passed to called function with the address: function_address, count:  is the len of data, type: indicate the return type, can be int, float, double, long.

 

so I need to implement by assembley, can't use some thing like: function_address(.....) to call directly. 

seems no inline asssembly can reach arm, but assembly can. can you give me an example of how to implement callfunction?

 

so thanks

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>I need to implement a call function interface.

 

Are you writing some kind of interpreter?

 

>void* callfunction(int *data, int *type, int count, void* function_address).

 

What is this function returning in the void*?

The proper declaration for a generic function is: void (*function_address)(void)

 

>data: this array contains the parameters which will be passed to

 

Are there count int parms by value?

 

>so I need to implement by assembly,

 

You can't do this in assembly either.

 

>can't use some thing like: function_address(.....) to call directly. 

 

You can but you need a doubly nested switch, one for the return type and one for the data parms.

For each return type and parms, you'll need to cast function_address to that function.

switch (*type) {

case T_int:

   int ii = ((int (*)(int))function_address)(data(0));

 

I'm not sure how you are encoding your data array and count?

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

> switch (*type) {

> case T_int:

>   int ii = ((int (*)(int))function_address)(data(0));

 

this is exactly the usage of this function, not the implementation. it needs return void* because it can return int, long, double, float, or a pointer. void* can be cast to any type.

 

"type" array indicates the type of data element, which can be int, float, long, double, pointer.

"count" indicates the length of type array.

"data" is an int array, but it is only a memory block, which will hold data format: int, float, long, double, pointer, according to the relative type.

 

the aim of data, type, and count is that: we can get input parameters for function whose address is function_address.  the design of callfunction is to call any functions with differenet number & type of paramters.

 

because IA-64 use registers from r32 as in/local/out registers, and pass parameters by out registers, it is hard to let callfunction to call any number parameters functions. so I limit the called funtions' params' number to 4. that means called function at most has 4 parameters.

 

thanks for your reply.

I have implemented callfunction by asm.

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

oh, 

> switch (*type) {

> case T_int:

>   int ii = ((int (*)(int))function_address)(data(0));

it is calling the function whose address is function_address. but the calling function's params' number is not fixed, it can have no param, or many. so I get no idea that I can directly call in this way.

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>It needs return void* because it can return int, long, double, float, or a pointer. void* can be cast to any type.

 

A void* can only be cast to a pointer to objects, not double/float, etc.

And if cast to a pointer, where is it going to point, if the function really returns an int?

 

>the aim of data, type and count is that: we can get input parameters for function whose address is function_address.  the design of callfunction is to call any functions with different number & type of parameters.

 

Unless you have a more complex description of this, you can't do it with just those three.

 

>because IA-64 use registers from r32 as in/local/out registers, and pass parameters by out registers, it is hard to let callfunction to call any number parameters functions. So I limit the called functions' parms' number to 4. That means called function at most has 4 parameters.

 

The max is 8.  The rest are on the stack.

 

>but the calling function's parm number is not fixed, it can have no parm or many.

 

You must have a switch for each possible case.  Or always pass 8 parms.

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

> A void* can only be cast to a pointer to objects, not double/float, etc.

 

it is not true. void* is a pointer, and a pointer can be cast by forcely to any other types. only need they have the same bytes. for example:

 

void* p = ...;

int ip = (int)(long)p; // for 64bit, pointer is 8 bytes, but int only 4 bytes, so first cast to long, then to int. but will lose 0x60000000000000000000

 

> if cast to a pointer, where is it going to point, if the function really returns an int?

 

it will truely cause an error under 64bit, but is okie under 32bit. when call a function, accroding to the return type, it will use the different return value funtion. if return type is float, float returning function will be called, e.g.

 

> The max is 8.  The rest are on the stack.

 

this is useful. thanks. :-)

 

> You must have a switch for each possible case.  Or always pass 8 parms.

 

correctly. that is the reason why I need assembly. because directly call as you suggested  can't reach this aim. because of different number of params.

 

thanks for your great help.

 

 

 

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

what I have done is this: according to the number of params of called function, I use a switch to every case. but limit the number of params to 4 at most
jufengyao
Advisor

Re: how to call a function by aCC inline assembly

but now, I think I can let it has full function: allow to calling function with any number of parameters
Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>it is not true. void* is a pointer and a pointer can be cast by forcedly to any other types. only need they have the same bytes.

 

This is a reinterpret_cast and implementation defined and so non-portable.

>that is the reason why I need assembly. because directly call as you suggested can't reach this aim. because of different number of parms.

 

No, assembly has the same problem, unless dynamically generated.  And you can pass more parms than are used.

 

> allow to calling function with any number of parameters

 

You would need a fixed maximum.  And if you have structs by value, you would have to handle that too.

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

> No, assembly has the same problem, unless dynamically generated.  And you can pass more parms than are used.

 

seems yes. I find that assembly of Itanium is more diffcult than X86. it uses out registers for int & pointer parameters, f registers for float & double parameters. if I want to let it call function with any params types and any number of params, it is seems hard. but if I use stack, can I get this aim?

 

also I'm agree with that passing more params, and group the same type params: double group, float group, int group, pointer group. but this seems still not enough. 

 

I can only use 8 f registers? if that is true, can I use stack to passing more float & double params?

 

thanks

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>if I want to let it call function with any parms types and any number of parms.  But if I use stack, can I get this aim?

 

There is no stack.  You must pass the first 8 parms in the appropriate registers.  Then you must pass the rest in the parm area in the stack frame.  And you really can't do "any", only a fixed max.

 

>group the same type parms: double group, float group, int group, pointer group. But this seems still not enough.

 

Not sure what you mean by group?  There are either GR or FR parms.

 

>I can only use 8 f registers? Can I use stack to passing more float & double parms?

 

Yes, there are only 8.  The rest are in the stack frame.

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

 

 

 

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

thanks for your help. I have implemented, the max called function param can be 8, under both 32bit & 64bit mode. although it is not perfact, because it can't call function that has params more than 8. 

 

please help me: how to operate stack frame?

 

thanks.

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>but what I don't know is how to operate stack frame.

>can you give me an simple example that how to create stack frame (if needed), and put the parms into it.


Take a look at the -S output of a function that has more than 8 parms.   Also look at the caller.

Here is where doing it in the compiler helps.

Though if you have floating point, you would need a switch of 3 ** 8 to handle all of the combinations of integral, float and double parms.  In assembly you could just have the 8 * 2 IFs.
 

jufengyao
Advisor
Solution

Re: how to call a function by aCC inline assembly

> Take a look at the -S output of a function that has more than 8 parms. 

 

thanks. it is really a wonderful idea!

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

> if you have floating point, you would need a switch of 3 ** 8 to handle all of the combinations of integral, float and double parms.  In assembly you could just have the 8 * 2 IFs.

 

actually, only 4 switch cases under 64bit & 32bit mode. because I need read double, float, int and pointer, total 4 types. all pointer type are the same: 4 bytes under 32bit and 8 bytes under 64bit. I only need to pass the pointer to called function.  

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>>you could just have the 8 * 2 IFs.

 

Two IF tests but three cases.

 

>int and pointer, total 4 types.

 

Integral and pointer can be treated almost the same.

 

 

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

> Integral and pointer can be treated almost the same.

 

true under 32bit, but false under 64bit. pointer is 8 bytes under 64bit, but 4 bytes under 32bit. while int always 4 bytes under both 32bit & 64bit

 

I have investigated the assembly which aCC genereated. and find a sad thing: even use stack to pass parameters (if more then 8 params), still need addtional registers to pointer the address which contains the value of parameters. here is the detail:

(if calling a function with 13 parameters)

p1~p8 -> passed by proper registers (out or f register)

p9   -> r14 (holds the address of stack which contains the value of p9)

p10 -> r11

p11 -> r10

p12 -> r9

p13 -> r8

 

2 sad things: every parameter (from p9 ~ p13) still need a register to hold the address of its value; and r12, r13 are special registers. 

 

I guess when the called function wants to fetch p9~p13, it should first look at r8~r14 to get the address on stack, then use this address to fetch the value. some thing like this:

ldfd  f8=[r8] // if p13 is double

ldfs  f9=[r9] // if p12 is single float

ld4  loc1=[r10] // if p11 is int or pointer under 32bit

 

this means I still can't call any number of functions.

 

maybe limit the max number of params to 8 is the best, and simplest.

Dennis Handly
Acclaimed Contributor

Re: how to call a function by aCC inline assembly

>true under 32bit, but false under 64bit. pointer is 8 bytes under 64bit, but 4 bytes under 32bit. while int always 4 bytes under both 32bit & 64bit

 

Note: I said integral, not int.  (There is no need to explain these details to me. ;-)

 

As far as the calling convention is concerned, you can treat them the same.  They all go into a 64 bit register that doesn't have to be signed extended by the caller.  You do need to have a switch to extract the proper size out of your "data" array.

And if they are structs by value, they do need to be left justified.

 

>still need additional registers to point to the address which contains the value of parameters.

 

Not really, these are just scratch registers to do the load and stores.

 

>still need a register to hold the address of its value

 

The same as any other load and store.  This isn't important and is computed as needed.

 

>it should first look at r8~r14 to get the address on stack

 

No, these are scratch.  It addresses these from the previous SP in r12.  Did you look at the code for the callee?

 

>this means I still can't call any number of functions.

 

Other than the fixed maximum of args and the number of switch case, you still can.

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

> No, these are scratch.  It addresses these from the previous SP in r12.  Did you look at the code for the callee?

 

Dennis, I have great interesting in this. I investigate the code for callee, and got what I said, but what I said was what I guess. still don't know what exactly the called function does to find the inputted params.

 

can you please describe more detailly? till now, I can't find useful document of this. so thanks. :-)

jufengyao
Advisor

Re: how to call a function by aCC inline assembly

find some thing helpful of x64:

sp+0 ~sp+0x20 is reserved, the passed parameters is put begin sp+0x20. seems IA64 is the same.

still some questions: if I pass int, double, int, double by stack, how are they placed? like this:

sp+0x20 -> int
sp+0x28 -> double
sp+0x30 -> int
sp+0x38 -> double

because of align. right?
jufengyao
Advisor

Re: how to call a function by aCC inline assembly

get new information.

 

suppost I need to pass 4 parameters: int, double, int, double. here what I do:

 

add  sp=-48,sp// keep enough spaces for 4 params & 16 bytes 'red zone'

// ld4 int into loc2

add loc3=16,sp  // pass param begin from sp+0x10

st4  [loc3]=loc2

// ldfd double into f7

add loc3=24,sp // maybe need adjust loc3 because of align 8

stfd [loc3]=f7

.......

 

please check this code, and give me any suggestions. 

thanks