Calls using labels

65 views
Skip to first unread message

Hainz

unread,
Oct 29, 2011, 11:17:51 AM10/29/11
to asmjit-dev
I'm currently translating HLSL shaders to x86 using AsmJit::Compiler.
How can I insert procedures (call it and return from proc to
instruction after call instruction) into my JIT code? Am I supposed to
create multiple functions or can I use labels (ECall* call(const Label
&label))? Multiple return statements cause an assertion being invalid.
There are only samples of 'absolute' function calls to compiler
generated functions.

Anyway great library! Thank you!

Petr Kobalíček

unread,
Oct 29, 2011, 1:13:20 PM10/29/11
to asmji...@googlegroups.com
Hi Hainz,

There is a way to create more functions and call them using call(const
Label&), but you can do this by using single pass, creating more
functions using single AsmJit::Compiler instance.

If you create a EFunction object using
AsmJit::Compiler::newFunction(), then you can call getEntryLabel() to
get the function entry-point.

For example:
Compiler c;

ECall* ctx;
EFunction* funcA = c.newFunction(CALL_CONV_DEFAULT,
FunctionBuilder1<int, int>());

funcA->getEntryLabel();
// ...

But I see the problem here that you want to generate some function
after the funcA is serialized, in this case there is quite hacky way
how the another function can be called,

for example:

Compiler c;
Label bLabel;

// Generate funcA.
EFunction* funcA = c.newFunction(CALL_CONV_DEFAULT,
FunctionBuilder1<int, int>());

// Call a function b which will be generated later.
c.call(bLabel);
// ...
c.endFunction();

// Generate funcB, I'm going to use custom label bLabel which points
to the entry-point.
c.align(16);
c.bind(bLabel);
EFunction* funcB = c.newFunction(CALL_CONV_DEFAULT,
FunctionBuilder1<int, int>());
// ...
c.endFunction();

// ...
c.make();

I'm going to evaluate this issue and to propose a better solution.

Hope that helps.

BTW: I'm going to create a shader engine too for the Fog-Framework,
but it will be 2d only, maibe we can share some ideas in the future;)

Best regards
Petr Kobalicek

Hainz

unread,
Oct 29, 2011, 5:05:47 PM10/29/11
to asmjit-dev
I set up a test case quickly for the second sample and it works. This
way the shader function call stuff should be implementable quite
smartly.

> I'm going to evaluate this issue and to propose a better solution.
The only idea/wish I can contribute here is to avoid the function
declaration redundancy.

> BTW: I'm going to create a shader engine too for the Fog-Framework,
> but it will be 2d only, maibe we can share some ideas in the future;)
Though I suspect that I'm not able to hold a candle to you (yet ;))
but I'll try my best.


Thank you very much for sharing this great project!




int main(int argc, char* argv[])
{
typedef int (*FuncType)(int);

Compiler c;
FileLogger logger(stderr);
c.setLogger(&logger);

Label bLabel = c.newLabel();

auto funcA = c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder1<int,
int>());
{
auto other = c.newGP();
c.mov(other, c.argGP(0));
c.add(other, other);

auto var = c.newGP();
auto ctx = c.call(funcBLabel);
ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder2<int, int,
int>());
ctx->setArgument(0, c.argGP(0));
ctx->setArgument(1, other);
ctx->setReturn(var);

c.add(var, var);
c.ret(var);
c.endFunction();

// return 8 * arg_0
}

c.align(16);
c.bind(funcBLabel);
auto funcB = c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder2<int,
int, int>());
{
c.add(c.argGP(0), c.argGP(0));
c.add(c.argGP(0), c.argGP(1));
c.ret(c.argGP(0));
c.endFunction();

// return 2 * arg_0 + arg_1
}

auto f = function_cast<FuncType>(c.make());

int i;
std::cout << "input integer: ";
std::cin >> i;

auto result = f(i);
auto expected = i * 8;

std::cout << "result: " << result << " (expecting " << i << " * 8
= " << expected << ", result " << ((result == expected) ? "CORRECT" :
"WRONG") << ")" << std::endl;

wxfstock2005

unread,
Oct 30, 2011, 9:07:28 PM10/30/11
to asmji...@googlegroups.com
thank you? can you give me your msn,i want to add you and chat with you  about the  asmjit.




网易公开课推出哈佛最受欢迎《幸福》课程,帮您修满幸福学分!

Petr Kobalíček

unread,
Oct 30, 2011, 10:27:50 PM10/30/11
to asmji...@googlegroups.com
Hi,

please always use AsmJit mailing list to ask for questions about
AsmJit, this will help others and minimize asking of questions which
has been already answered. I'm available on gmail chat quite often, so
if you need something really important, you can find me there.

And reply for Hainz:

Currently the declaration reduncancy can be avoided by using
setCurrentEmittable(), but I'd like to warn you, because it's not well
tested (personally, I had never used this). If you want to experiment,
try to use something like this:

Compiler c;

EFunction* funcA = c.newFunction(CALL_CONV_DEFAULT, ...);
EFunction* funcB = c.newFunction(CALL_CONV_DEFAULT, ...);

// Generate function A.
c.setCurrentEmittable(funcA);
// ...
ECall* ctx = c.call(funcB->getEntryLabel());
// ...

// Generate function B.
c.setCurrentEmittable(funcB);

By using this technique you can combine it with hash table so you get
"symbol" -> EFunction mapping. This technique generally uses the
design of AsmJit::Compiler which allows to add/remove instructions
before the c.make() is called. You can post-process the generated code
by using this technique to optimize or reorder it. It should be
probably more highlighted in the documentation.

Note, a new emittable (instruction, label, call) is always added after
the current emittable. The list is implemented as double-linked list
so you shouldn't worry about performance, it's O(1).

Best regards
Petr Kobalicek

wxfstock2005

unread,
Nov 14, 2011, 8:10:29 PM11/14/11
to asmji...@googlegroups.com

Hi all,
     If i use  the setCurrentEmittable function ,i can  make more function in one c Compiler ,before one c compiler just can make one function,but how can i call the function which is not the main function. such as
>Compiler c;
>
>EFunction* funcA = c.newFunction(CALL_CONV_DEFAULT, ...);
>EFunction* funcB = c.newFunction(CALL_CONV_DEFAULT, ...);
>
>// Generate function A.
>c.setCurrentEmittable(funcA);
>// ...
>ECall* ctx = c.call(funcB->getEntryLabel());
 >c.endFunction();
>FuncType f = function_cast<FuncType>(c.make());
How can i call the function   funcB?
thanks you!!!

Petr Kobalíček

unread,
Nov 20, 2011, 11:17:04 AM11/20/11
to asmji...@googlegroups.com
Hi,

I'm going to evaluate this and to improve the mechanism to get the
function pointer/offset.

Best regards
Petr Kobalicek

wxfstock2005

unread,
Nov 21, 2011, 7:12:13 AM11/21/11
to asmji...@googlegroups.com
OK,thanks.

wxfstock2005

unread,
Nov 22, 2011, 8:08:46 PM11/22/11
to asmji...@googlegroups.com
HI ALL:
    I want to write a compiler such as c languege with the asmjit,someone can give me some advice?

wxfstock2005

unread,
Nov 29, 2011, 3:37:25 AM11/29/11
to asmji...@googlegroups.com
HI ALL:
    How can i write this function with the Compiler?
   thanks
 
  int MyCall(int a)
 {
     if( a> 1)
          return a+MyCall(a-1);
    return 1;
}

Petr Kobalíček

unread,
Nov 30, 2011, 8:00:29 PM11/30/11
to asmji...@googlegroups.com
Hi,

calling recursively one function is actually easy, please take look at
the test file called testfuncrecursive1.cpp, svn version here:

http://code.google.com/p/asmjit/source/browse/trunk/AsmJit-1.0/Test/testfuncrecursive1.cpp

Hope that helps
Petr Kobalicek

wxfstock2005

unread,
Dec 8, 2011, 9:36:12 AM12/8/11
to asmji...@googlegroups.com
thanks for your  test code;

Reply all
Reply to author
Forward
0 new messages