You are reading a single comment by @fanoush and its replies. Click here to read the full conversation.
  • I don't know what the implication is to support float directly, but it does sound like a good alternative to doing the conversion in C. The conversion needs to happen somewhere. Is it better to have it in Espruino, where it will take up space even if you don't use compiledC, or is it better to have in each compiledC block that uses doubles?

    Personally, I don't really need to pass floats/doubles to/from C. Just being able to work with floats is enough for me. I merely replied with a working version of the code that was asked for.

  • Is it better to have it in Espruino, where it will take up space even if you don't use compiledC, or is it better to have in each compiledC block that uses doubles?

    Well, the conversion code already takes that space in Espruino due to Float32Array. I just tried to implement float type support for native calls in espruino and with this small patch (also attached) it works

    diff --git a/src/jsnative.c b/src/jsnative.c
    index fb1f20a22..201a158a7 100644
    --- a/src/jsnative.c
    +++ b/src/jsnative.c
    @@ -145,6 +145,12 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
         case JSWAT_INT32: // 32 bit int
           argData[argCount++] = (uint32_t)jsvGetInteger(param);
           break;
    +    case JSWAT_FLOAT32: { // 32 bit float
    +      union {uint32_t i; float f;} v; // with softfp convention float values are passed in integer registers
    +      v.f = (float) jsvGetFloat(param); // truncate from double
    +      argData[argCount++] = v.i;
    +      break;
    +    }
     [#ifndef](https://forum.espruino.com/search/?q=%23ifndef) ESPR_EMBED
         case JSWAT_PIN: // 16 bit int
           argData[argCount++] = (uint32_t)jshGetPinFromVar(param);
    @@ -265,6 +271,11 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
         return jsvNewFromInteger((JsVarInt)result);
       case JSWAT_JSVARFLOAT: // 64 bit float
         return jsvNewFromFloat(*(JsVarFloat*)&result);
    +  case JSWAT_FLOAT32:  {// 32 bit float
    +    union {uint32_t i; float f;} v; // with softfp convention float values are passed in integer registers
    +    v.i = (uint32_t)result;
    +    return jsvNewFromFloat((JsVarFloat)v.f);
    +  }
       default:
         assert(0);
         return 0;
    diff --git a/src/jswrap_espruino.c b/src/jswrap_espruino.c
    index 1d6ef5cba..80ccf61f7 100644
    --- a/src/jswrap_espruino.c
    +++ b/src/jswrap_espruino.c
    @@ -196,6 +211,7 @@ int nativeCallGetCType() {
         if (strcmp(name,"bool")==0) t=JSWAT_BOOL;
         if (strcmp(name,"Pin")==0) t=JSWAT_PIN;
         if (strcmp(name,"JsVar")==0) t=JSWAT_JSVAR;
    +    if (strcmp(name,"float")==0) t=JSWAT_FLOAT32;
         jslMatch(LEX_ID);
         return t;
       }
    diff --git a/src/jswrapper.h b/src/jswrapper.h
    index 99866f0dd..c60a55069 100644
    --- a/src/jswrapper.h
    +++ b/src/jswrapper.h
    @@ -43,6 +43,7 @@ typedef enum {
       JSWAT_BOOL, ///< boolean
       JSWAT_INT32, ///< 32 bit int
       JSWAT_PIN, ///< A pin
    +  JSWAT_FLOAT32, ///< 32 bit float
       JSWAT_JSVARFLOAT, ///< 64 bit float
       JSWAT__LAST = JSWAT_JSVARFLOAT,
       JSWAT_MASK = NEXT_POWER_2(JSWAT__LAST)-1,
    

    Tested with

    var c = E.compiledC(`
    // float fadd(float,float)
    // float fmul(float,float)
    
    float fadd(float f1,float f2){
    return f1+f2;
    }
    float fmul(float f1,float f2){
    return f1*f2;
    }`);
    print(c.fmul(1.5,-1.5));
    print(c.fadd(1.5,-0.25));
    

    and I get

    >-2.25
    >1.25
    

    EDIT: after comparing output of
    echo 'int main(){return 0;}' | arm-none-eabi-gcc -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -xc - -dM -E | sort
    for different calling conventions it looks like the code in jsnative.c and jswrap_espruino.c could be #ifdef-ed by __ARM_PCS so that it is there only for ARM soft/softfp builds.


    1 Attachment

About

Avatar for fanoush @fanoush started