How to write wrapper for VCVT ARM instruction?

Asked by jdobry on 2018-04-04

Hi,

I am trying to write wrapper to use ARM instruction to float point to fixed point conversion.
Here is first idea:

  __attribute__((always_inline)) static inline
  int arm_F32toFixPointI32 (float x, int bits)
  {
    int y;
    __asm__ __volatile__ (
      "VCVT.s32.f32 %[y], %[x], %[bits]"
        : [y] "=t" (y) /* output */
        : [x] "t" (x), [bits] "I" (bits) /* input(s) */
        : /* list of clobbered registers */);
    return y;
  }

But there is problem. I could work only if "x" and "y" are in same register.
How to tell GCC that input and output from ASM code are in same register, but with different type?

I try this, but it can't work anyway:
  __attribute__((always_inline)) static inline
  int arm_F32toFixPointI32 (float x, int bits)
  {
    __asm__ __volatile__ (
      "VCVT.s32.f32 %[x], %[x], %[bits]"
        : [x] "+t" (x) /* output */
        : [bits] "I" (bits) /* input(s) */
        : /* list of clobbered registers */);
    return x; // <-here is problem. Compiler add instruction to convert "x" from "float" to int.
  }

Any idea how to code this?
Jiri

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Thomas Preud'homme
Solved:
2018-04-06
Last query:
2018-04-06
Last reply:
2018-04-05
jdobry (jdobry) said : #1

This code works, but itsn't perfect solution because force compiler to use s15 register only and made limitation for register optimalizations
  __attribute__((always_inline)) static inline
  int arm_F32toFixPointI32 (float x, int bits)
  {
    register float s15 __asm__("s15") = x;
    register int y __asm__("s15");
    __asm__ __volatile__ (
      "VCVT.s32.f32 %[y], %[y], %[bits]"
        : [y] "+t" (s15) /* output */
        : [bits] "I" (bits) /* input(s) */
        : /* list of clobbered registers */);
    return y;
}

Hi,

Have you tried using the constraint "0" for x instead of t? It should force it to be in the same register as the first operand (ie the output).

Best regards.

jdobry (jdobry) said : #3

Thanks Tomas to pointing me to solution.
This code is what I wanted to have:

  __attribute__((always_inline)) static inline
  int arm_F32toFixPointI32 (float x, int bits)
  {
    int y;
    __asm__ __volatile__ (
      "VCVT.s32.f32 %[y], %[x], %[bits]"
        : [y] "=t" (y) /* output */
        : [x] "0" (x), [bits] "I" (bits) /* input(s) */
        : /* list of clobbered registers */);
    return y;
  }

jdobry (jdobry) said : #4

Thanks Thomas Preud'homme, that solved my question.