Skip to content
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

asm.js support #332

Closed
maks opened this issue Apr 17, 2014 · 11 comments
Closed

asm.js support #332

maks opened this issue Apr 17, 2014 · 11 comments

Comments

@maks
Copy link

maks commented Apr 17, 2014

I spotted http://forum.espruino.com/conversations/957/#comment13946 (sorry I can't seem to login to the forums right now) but my idea was about using asm.js (https://github.com/dherman/asm.js/) as the "inline assembly" in Espruino.

What I had in mind was given that asm.js is a nice simple subset of JS, to write a basic compiler for it into ARM assembly and then have an ARM assembler assemble that into ARM machine code that code be poked into flash and then called as @gfwilliams you suggested in that forum comment.

I realise that the ARM instruction set is not that small or simple and I've not done ARM assembly before, so I was going to first try prototyping this approach on AVR instead, where there's a much smaller/simpler 8bit instruction set and someone has already written a working assembler in JS (https://github.com/tadpol/Avrian-Jump) to get me started. And with AVR, especially the smaller ones, theres not much chance of getting the espruino js interpreter running but I'd still like to be writing JS for them using the excellent espruino WebIDE chrome app and maybe even getting support for the stk200 protocol into the webide to get arduino uploads working from it too :-)

Talking about "poking" and 8bit assembly, this would kind of be like the old school assembly/machine lang approach from the old 6502/z80 days as was described in the excellent Usborne book: https://boingboing.net/2013/05/16/1983s-wonderful-introducti.html though perhaps I'm the only one here old enough to remember the bbc/vic20/c64 days :-)

@loop23
Copy link

loop23 commented Apr 18, 2014

That would be a kick ass idea. Being able to write js which performs like assembler. Absolutely, go for it. Time permitting I may even lend a hand, but I can't promise anything!
And no, you're not the only one remembering those machines, I had a speccy myself!

@maks
Copy link
Author

maks commented Apr 18, 2014

Thanks for the encouragement! I'm only doing this in my limited spare time but anyone else even remotely interested is very welcome.
Also I should clarify that what I have in mind is running both the compiler and assembler in the chrome packaged app IDE, not on the devices themselves.
And finally I should have linked to the actual asm.js spec which is: http://asmjs.org/spec/latest/
The module http://www.espruino.com/STM32F1Flash seems to pretty much provide the "poke" functionality required, so I guess I just need to start being able to generate some ARM machine code...

@gfwilliams
Copy link
Member

Hi. It'd be a good idea - my concern was really that people would just use Emscripten, which may end up producing code that was too bloated (my original plan was to work on inline C). Personally I'd dive right in with ARM Thumb - it's pretty easy (probably more so than AVR). See the assembler as it currently is:

https://github.com/espruino/EspruinoWebIDE/blob/master/js/plugins/assembler.js

(you could just create another plugin pretty easily) and the documentation on it:

http://www.espruino.com/Assembler

They use poke to put code at the end of the stack - so they write it into RAM (not using that module), not flash. That would be the best way to start - and maybe move onto writing into flash later on :)

Perhaps the most sensible options is to just write C code for the functions you want, and then to compile it with GCC - which will give you the exact binary data you need to insert for that function.

The Web IDE already has a (very simple) JavaScript lexer, so actually handling asm.js could end up being relatively easy.

Just to add - if the assembler ended up being relatively simple (which IMO it could be), I'd be very interested in adding it to the Espruino C code itself.

@maks
Copy link
Author

maks commented Apr 20, 2014

@gfwilliams wow! I didn't even realise the assembler was already there, your work on this project just keeps blowing me away at every turn!

I completely agree, using Emscripten for this would be aweful and I certainly would hope people wouldn't.

And yes, just compiling with gcc would be the sensible option, but I'd love to be able to just still do all this with a Chromebook and the existing webIDE. And again apologies for my lack of research, I didn't know the JS lexer was already there as well, so using it would be a good option and now that I've started looking at the thumb ref you linked to on the assembler page this all looks doable, I'll go off and starting prototyping, thanks again!

@gfwilliams
Copy link
Member

No problem - thanks for looking into this! Sadly the existing assembler still needs a lot of work (more ops, and label support). If you find a JavaScript one that will do Thumb, it would probably make more sense to use that instead...

If you're up for a challenge, there's the Tiny C compiler (http://bellard.org/tcc/) which can be compiled into JavaScript with Emscripten (I've already tried this) and which creates ARM code already. Sadly the Cortex M3 can't run ARM code and needs to run Thumb/Thumb-2 instead. If Thumb support could be added to TCC it'd be epic (it'd probably be useful for a bunch of other stuff outside Espruino too), or even a ARM->Thumb converter might be a possibility (as the code is so similar).

While asm.js if cool, I guess inline C is probably of more use to people...

@maks
Copy link
Author

maks commented Jun 19, 2014

@gfwilliams sorry I'm just coming back to this now after being caught up on so many other projects. I think you are right, having inline C code would be very useful and probably a better and easier start than asm.js

Yes I've been along time admirer of tcc :-) and I am actually really happy that you got tcc compiled with Emscripten as I had thought to try that a while back back came across a SO q&a which said it wouldn't work because tcc had inline assembly. If you have any notes or pointers on "Emscripting" tcc I'd be very grateful for them and I'm keen to have a go though I do have a nagging doubt about the code it will spit out as its wikipedia entry says this:

"TCC compiles every statement on its own, and at the end of each statement register values are written back to the stack and must be re-read even if the next line uses the values in registers (creating extraneous save/load pairs between statements)"

But I'm keen to get it going via Emscripten and find out for myself and not blindly trust what others have written on the net :-)

@gfwilliams
Copy link
Member

Maybe TCC has inline assembly for x86->x86 compiles - but when cross-compiling I guess there's no point. It sure seemed to work fine with emscripten when I tried it. As I recall it was trivial to compile (no code changes needed).

The assembler TCC generated wasn't optimised, but it didn't look bad. gcc -O3 is going to be maybe twice as fast, but even the unoptimised code will be pretty speedy compared to JS on Espruino :)

Just a thought - but if you don't want to mess with TCC (although I'm sure they'd appreciate a Thumb port) you could write some JavaScript that took the ARM assembly and converted it to Thumb. The assembly that TCC generates is pretty simple and would probably map 1:1 to Thumb opcodes.

@gfwilliams
Copy link
Member

I've had a look at this recently and have had some success with TCC + Thumb. I've modified the file arm-gen.c and have got it producing valid thumb assembler for very basic functions like int x() { return 5; }. I can provide that if needed but it's still a hard slog to map every ARM instruction to its Thumb equivalent, especially as it's not really big on documentation.

That got me thinking that perhaps a more useful solution is actually to produce a JavaScript ARM disassembler (which is relatively easy) that disassembles to a file that can then be re-assembled into Thumb. Seems like a neat tool to have anyway, and it has the bonus of being pretty easy to debug because you're mostly dealing with human readable output.

@maks
Copy link
Author

maks commented Aug 13, 2014

@gfwilliams hey, that sounds great! Sorry I've dropped the ball on this and not had time to work on this myself but I'm still very interested. Would you have any diffs or a repo where you've done the work so far with TCC?

@gfwilliams
Copy link
Member

I just uploaded it: https://github.com/gfwilliams/tinycc/tree/thumb

Check out the README.md - I've tried to cover what I've done. I didn't change that much as it was really just a proof of concept, but it shouldn't be too painful to map the relevant Thumb instructions.

@gfwilliams
Copy link
Member

I think you've noticed this now, but there is now: http://www.espruino.com/Compilation

With more work on the compiler (details in that page), it could keep track of variable types and could then perform integer operations as native instructions (rather than passing them off to jsvMathsOp).

Closing this, so we can keep track of it on this issue in EspruinoTools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants