-
• #2
Awesome, glad you're diving in :)
Where are the parameters, and how could I interpret those ?
They're generated by
scripts/build_jswrapper.py
in Espruino itself - you can use anything that some other function in Espruino uses. At the moment this is:... edit: no longer relevant - 1v61 handles all different types ...
I'll be trying to change this though, so that Espruino can take a much larger variety of types.
Big question, as far as I can see, r0 is used in the example for input and return value
It's the way values are passed to functions on ARM: http://en.wikipedia.org/wiki/Calling_convention#ARM
Would it be possible to have something like a list of "interesting entrypoints". There is something like spi_sender_software in jswrap_spi_i2c.c This could be an additional file created during compilation of new version, and could be used similiar to boardinfo.
If you compile yourself, there's
espruino_1v##_espruino_1r3.lst
which actually has this in - I guess this could be included in the binaries folder. IMO it might be more sensible if Espruino itself could return a list of these functions and then the assembler could load them in.This would be way more useful if/when someone gets a C compiler working though. For now it would probably be easier (maybe even faster) to do SPI in software.
-
• #3
Based on last daily, I did some more testing.
Your link to Calling_convention gave a first help.
In my best understanding reg0 to reg3 are used for getting data.
By testing this, I could get 4 values back, but where is the 5th ?var adder = E.asm("int(int,int,int,int,int)", "mov r0,rn", where n is 1 to 3 "bx lr");
Another problem is JsVar, how could this be interpreted ?
I would like to play around with Uint-Arrays.
This one works, but now I want to change a value in the array.
My understanding of C is too poor to get this out of the sources.var x,i; x = Uint8Array(10); for(i = 0; i < 10; i++) x[i] = i; var adder = E.asm("JsVar(JsVar)", "bx lr"); adder(x)
-
• #4
After the first 4 values, they get put on the stack and you have to copy them off. But first you have to save the value of any registers above r3 that you might overwrite!
It's all getting quite complicated by that point.
Accessing the JsVars from assembler is going to be really difficult too I'm afraid - I wouldn't advise it. For now it's probably best just to call with:
for(var i in a) adder(a[i]);
Annoyingly
map
andforEach
don't work on Typed Arrays. I'm quite tempted to add support though :/EDIT: It's been pointed out to me that you can re-purpose the existing map function:
[].forEach.call(a, adder);
This won't work in 1v60, but I've just fixed
map/forEach
so that they will work on the latest build (or when 1v61 comes out). Note thatmap
will create an old-style array from the result, so you'll run out of memory pretty quickly.forEach
is fine though. -
• #5
Just to add that in 1v61 you'll be able to use
Array.reduce
too - which will be extremely useful if you want to do some analysis on an ArrayBuffer with inline assembler.For instance maybe you want to sum up all the values in an ArrayBuffer...
// effectively function (a,b) { return a+b; } var adder = E.asm("int(int,int)", "adds r0, r0, r1", "bx lr"); // fill up array buffer var a = new Int16Array(100); for (var i in a) a[i]=i; // Call our assembler on every item var sum = [].reduce.call(a, adder); console.log(sum); // 4950
-
• #6
During my learningphase I created an ASM call which only returns one out of a row of parameters. Parameter are stored in reg and in stack.
This is compiled with an external compiler (FASM), it will not run directly with the one in WebIDE.
I still would like to work with Uint-arrays directly. I'm pretty sure this kind of data is stored in memory directly, at least this is what I would like to have :-) get.
Would it be an option to have a function, something like adressOfData() which returns startadress in memory for Uint-Arrays ?thumb; cmp r0,#0 ;1st parameter is pointer to following args beq return ;pointer to first arg which is in r0 cmp r0,#1 bgt isgt1 mov r0,r1 ;2nd arg is in r1 b return isgt1: cmp r0,#2 bgt isgt2 mov r0,r2 ;3rd in r2 b return isgt2: cmp r0,#3 bgt isgt3 mov r0,r3 ;4th in r3 b return isgt3: sub r0,#4 ;since 5th arg is somewhere else lsl r0,r0,#2 ;data uses 4 bytes, so left shift by 2 is like multiplication by 4 ldr r0,[sp,r0] ;load from stack return: bx lr ;return value is in r0
-
• #7
They're not stored as flat arrays - more of a linked list - See http://www.espruino.com/Performance and http://www.espruino.com/Internals - and the actual JsVar struct declaration
That's why it's important to iterate over the data rather than accessing individual elements...
-
• #8
My knowledge around c++ is poor. Compiling Espruino by myself is out of my knowledge too. Working with assembler is something I will have a fair chance.
Therefore I would like to ask if there is a "not complicated way" to do some of this in assembler- set values in an array (typed or not, it doesn't care)
- return an array
- return a string
- support call of internal function (old basic version had something like adressOf(spi.send) for that)
- set values in an array (typed or not, it doesn't care)
-
• #9
Without recompiling I don't think you can do what you want I'm afraid, as you need the 'lst' file to be able to access the functions you need.
By the way, If you could find an ARM assembler (or even a machine-readable description of ARM Thumb opcodes) that could be embedded in the Web IDE it'd be extremely useful.
@Gordon, you opened Pandora's box, so I decided to "let's see what inside".
My background is assembler long time ago, but not ARM.
It works, good news. So have a look at minor changes.
Add 7 instead of 2 is simple by altering first command to movs r2, #7 .
Double given parameter simply add this adds r0,r0,r0
BTW, interesting to work with 3 parameters.
switch to external assembler.
The internal assembler, even if limited is a good starting point.
By searching for a "full blown" assembler I found http://flatassembler.net/
At this point I learned something about THUMBS and ARM commands.
To get same results as in Gordons example this needs to be done.
As you can see, first line switches to thumb mode.
One of the main futures of an assembler is last line. You don't have to count the number of word ´s to get the adress of GPIO adress.
Ok, there is another difference, use dw instead of .word
Right now I read this with Hex Editor and type it in manually. Don't forget to switch the bytes ;-)
What about using 2 parameters for a function like this adder(2,3)
And I get an error no caller for argument 438
int, bool and Pin return an error.
Big question, as far as I can see, r0 is used in the example for input and return value
If somebody has more examples, please share it
During development of Display driver for ILI9341 Gordon mentioned something like "we could speed it up by using SPI.send with repeat option".
Would it be possible to have something like a list of "interesting entrypoints". There is something like spi_sender_software in jswrap_spi_i2c.c
This could be an additional file created during compilation of new version, and could be used similiar to boardinfo. A new processor for Web IDE could replace adresses and ....
Hey Gordon, its you who opened Pandora's box ;-))
Juergen