-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requst arm backend. #160
Comments
The MIR design was mostly oriented to 64-bit targets as 32-bit market share is decreasing. Integer regs are 64-bit wide in MIR (although a program can use only 32-bits for each reg by using 32-bit MIR insns only). But I kept in my mind possible usage of it for 32-bit targets too. Currently porting MIR to 32-bit targets approximately requires the same efforts as for 64-bit targets. You just need to use 2 hard regs for one MIR reg. To generate more efficient code (using one hard reg for MIR integer reg involved only in 32-bit insns), an additional analysis should be implemented in MIR-generator to say machine-dependent generator code that one hard register can be used for given MIR integer reg. |
Hi Vladimir, I see someone else has asked a similar question to the one I posted on your blog. I have no business playing here but I am fascinated by MIR. I was able to generate a.bmir from your seive code. I can run it using |
Okay, well I've set up a little project over here: https://github.com/RussellHaley/mircVM
cvm main.c: #include <stdio.h>
#include "mir.h"
#include "readfile.h"
int interp(char *str)
{
MIR_module_t m;
MIR_item_t func;
MIR_context_t ctx = MIR_init ();
size_t len = strlen (str);
MIR_scan_string (ctx, str);
m = DLIST_TAIL (MIR_module_t, *MIR_get_module_list (ctx));
MIR_load_module (ctx, m);
MIR_link (ctx, MIR_set_interp_interface, NULL);
MIR_val_t val;
MIR_interp (ctx, func, &val, 0);
MIR_finish (ctx);
return 0;
}
int main(int argc, char** argv)
{
char *str;
if(argc > 1)
{
if(readfile(argv[1], &str) == 0)
{
//~ printf("not cool %s", str);
interp(str);
}
}
else
{
printf("Need to pass a filename\n");
return 1;
}
if(str != NULL) free(str);
printf("That's all folks.\n");
return 0;
} |
Ah, okay I see now about loading externals. I'm running into this error now:
Which I've figured out is telling me my "func" variable isn't pointing to the right entry point (e.g. an item_type of 2)?
#include <stdio.h>
#include "mir.h"
#include "readfile.h"
int interp(char *str)
{
int retval = 0;
MIR_module_t m;
MIR_item_t func;
MIR_context_t ctx = MIR_init ();
size_t len = strlen (str);
MIR_scan_string (ctx, str);
m = DLIST_TAIL (MIR_module_t, *MIR_get_module_list (ctx));
if(m == NULL)
{
printf("Failed to get the module items\n");
retval = 2;
}
else
{
func = DLIST_TAIL (MIR_item_t, m->items);
if(func == NULL)
{
printf("WTH?");
}
else
{
printf("enum val %d\n", func->item_type);
printf("name %d\n", func->module->name);
}
MIR_load_module (ctx, m);
MIR_load_external (ctx, "printf", printf);
MIR_link (ctx, MIR_set_interp_interface, NULL);
MIR_val_t val;
MIR_interp (ctx, func, &val, 0);
}
MIR_finish (ctx);
return retval;
}
int main(int argc, char** argv)
{
char *str;
if(argc > 1)
{
if(readfile(argv[1], &str) == 0)
{
//~ printf("not cool %s", str);
interp(str);
}
}
else
{
printf("Need to pass a filename\n");
return 1;
}
if(str != NULL) free(str);
printf("That's all folks.\n");
return 0;
} |
Okay, finally got something working! #include <stdio.h>
//~ #include "mir-dlist.h"
#include "mir.h"
#include "readfile.h"
char *strings[] = {"func", "proto", "import", "export", "forward", "data", "ref_data", "expr_data"};
int interp(char *str)
{
int retval = 0;
MIR_module_t m;
MIR_item_t entry_point = NULL;
MIR_context_t ctx = MIR_init ();
size_t len = strlen (str);
MIR_scan_string (ctx, str);
m = DLIST_TAIL (MIR_module_t, *MIR_get_module_list (ctx));
if(m == NULL)
{
printf("Failed to get the module items\n");
retval = 2;
}
else
{
int len = DLIST_LENGTH(MIR_item_t, m->items);
MIR_item_t element;
for(int i=0; i<len; i++)
{
element = DLIST_EL(MIR_item_t, m->items, i);
printf("enum val %d\n", element->item_type);
printf("type %s\n", strings[element->item_type]);
printf("module %s\n", element->module->name);
if( element->item_type == 0 )
{
printf("name %s\n", element->u.func->name);
if(strncmp("main", element->u.func->name, 4) ==0)
{
entry_point = element;
break;
}
}
printf("----------------\n");
}
if(entry_point != NULL)
{
MIR_load_external (ctx, "printf", printf);
MIR_load_module (ctx, m);
MIR_link (ctx, MIR_set_interp_interface, NULL);
typedef int64_t (*loop_func) (void);
MIR_set_interp_interface (ctx, entry_point);
int64_t res = ((loop_func) entry_point->addr) ();
}
//~ MIR_val_t val;
//~ MIR_interp (ctx, func, &val, 0);
}
MIR_finish (ctx);
return retval;
}
int main(int argc, char** argv)
{
char *str;
if(argc > 1)
{
if(readfile(argv[1], &str) == 0)
{
//~ printf("not cool %s", str);
interp(str);
}
}
else
{
printf("Need to pass a filename\n");
return 1;
}
if(str != NULL) free(str);
printf("That's all folks.\n");
return 0;
}
I assume there is a better way to do this? I also assume I mutilated your rather spiffy DLIST. (I'll search for some examples in the code) |
wonderfull work:) |
Bit rot is real. My arm boards seem to spontaneously combust. I'm re-imaging a Hummingboard with a dual core NXP iMX6 (probably won't finish in time tonight). I also have an old beaglebone to test on. I have copied the Aarch64 files as Aarch32. Wikipedia says Aarch32 is the official term now. I do know that the "arm" moniker is the historic one. Thoughts @vnmakarov? FreeBSD was stuck referring to ArmV7 as ArmV6 for forever. As I am not an expert, my plan was to attempt to build on a 32 bit arm platform and see what explodes. I see that there are hard coded register values that will need to be examined. I am hoping this step down between Aarch64 and armv7/armv8a will inform me as to what I might need to step down to the arm M4F (specifically I'm aiming at an Stm32MF466). |
afaik aarch32 is the ILP32 ABI for aarch64, same as x32 for x86_64. so it does use 64 bit registers for speed, but long and pointers are 32bit unlike on real 64 bit binaries. |
Thank you for trying MIR.
You can run it with c2m: It is an experimental utility. I am planning to move its functionality into Still MIR and c2m is not for everyday C programmer. It is hard to develop C code with c2m (e.g. absence of debugging support) Currently It is mostly for developers of JITs. |
HJ Lu from Intel designed x32 and implemented it in GCC. FIrst it was promising but at the end it never flys. Now I guess it is a burden. I guess the same might happen with arm ilp32. Smaller code is important especially in container environments but few percent (or 10-20%) is not a big difference. But 100 times difference in code size of LLVM/GCC based JIT and MIR JIT compiler has some sense. |
I see. So it would not be an appropriate name. Thanks for clarifying. |
Thank you for clarifying. I did manage to figure out the tools a little after reading through the documents a few more times (and I did figure out the b2ctab.
Yes, I realize. But it sure is fun riding on your coat tails! The thought is just for prototyping a 32 bit port and gaining familiarity. |
Hello! Well I finally have an arm board working. @vnmakarov, your genius has even managed to foil my incompetence and I managed build and run/fail c2m on my beaglebone:
Pull request for comments is here: #162 |
Lolz. That was way more difficult then it should have been, I finally just built from git. Thankfully the OS image from beaglebone comes pre-installed with build-essential. Hurray for sanity! @vnmakarov, any chance I can convince you to switch to a sublime build system called xmake? Xmake installs everywhere and builds "everything". It's written in C/LuaJIT2 and it doesn't have the pitfalls of a meta build system like CMake. https://xmake.io/#/getting_started --> Check out the "Build as fast as ninja stats". |
I suggest not to do that, CMake have broader usage even though have so much pitfalls, and many IDE support CMake. |
Thank you for your work on arm32 port. It is a start. As I understand now with this patches we can generate MIR code from C on arm32. To make interpreter and generator working a lot of things still should be done. I'll review your pull request. It might take couple weeks or more (I need to learn arm32 C ABI for this and honestly I am busy with other projects until mid-April).
Sorry, no. CMake is also non-standard feature for MIR project (it was initially added by logzero for Windows port). MIR project can live without this. Currently I use make even when working on Windows. I guess it will stay this way. I don't see any advantages to use anything besides widely used make right now. One my goal is to keep minimum dependencies. That is why I don't use yacc/lex or any external libraries. |
No, it doesn't create anything yet. I will continue to hack away at this.
Is this the correct document to learn the arm32 C ABI? https://static.docs.arm.com/ihi0039/c/IHI0039C_clibabi.pdf I'm happy to play by myself if you could give me a hint as to where to drill into the VM code? To be honest, I want to know how a VM works; I could go buy an RPi4 if I really wanted to. I am elated about the readability of the code and want to take advantage of this situation. It's not everyday one finds C code of this caliber that is easily accessible.
You're a gentleman for even commenting on the idea. Thank you! |
As mir are so small, it's may suite for small soc, such as RPI2, RPI Zero and so on.
The text was updated successfully, but these errors were encountered: