]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: target/122222 - Add modules for __floatsidf, __floatunsidf.
authorGeorg-Johann Lay <avr@gjlay.de>
Thu, 9 Oct 2025 16:35:34 +0000 (18:35 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Thu, 9 Oct 2025 19:55:11 +0000 (21:55 +0200)
PR target/122222
libgcc/config/avr/libf7/
* libf7-asm.sx (D_floatsidf, D_floatunsidf): New modules.
* libf7-common.mk (F7_ASM_PARTS): Add D_floatsidf, D_floatunsidf.
(F7F, g_dx): Remove floatunsidf, floatsidf.
* libf7.c (f7_set_s32): Don't alias to f7_floatsidf.
(f7_set_u32): Don't alias to f7_floatunsidf.
* f7-renames.h: Rebuild
* f7-wraps.h: Rebuild.

gcc/testsuite/
* gcc.target/avr/pr122222-sitod.c: New test.

gcc/testsuite/gcc.target/avr/pr122222-sitod.c [new file with mode: 0644]
libgcc/config/avr/libf7/f7-renames.h
libgcc/config/avr/libf7/f7-wraps.h
libgcc/config/avr/libf7/libf7-asm.sx
libgcc/config/avr/libf7/libf7-common.mk
libgcc/config/avr/libf7/libf7.c

diff --git a/gcc/testsuite/gcc.target/avr/pr122222-sitod.c b/gcc/testsuite/gcc.target/avr/pr122222-sitod.c
new file mode 100644 (file)
index 0000000..d8f1720
--- /dev/null
@@ -0,0 +1,60 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+/* { dg-additional-options { -std=gnu99 -Os -mcall-prologues } } */
+
+#if __SIZEOF_LONG_DOUBLE__ == 8
+
+typedef long double D;
+typedef __INT32_TYPE__  int32_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT8_TYPE__  uint8_t;
+
+#define ARRAY_SIZE(X) (sizeof(X) / sizeof(*X))
+
+void testu (void)
+{
+  static const volatile __flash uint32_t vals[] =
+    {
+      0, 1ul, -1ul, (-1ul) << 1,
+      1ul << 31, 1ul << 30, 1ul << 29, 1ul << 28, 1ul << 27, 1ul << 26,
+      1ul << 25, 1ul << 24, 0xff, 123456789
+    };
+
+  for (uint8_t i = 0; i < ARRAY_SIZE (vals); ++i)
+    {
+      D x = (D) vals[i];
+      __asm ("" : "+r" (x));
+      if ((uint32_t) x != vals[i])
+       __builtin_exit (__LINE__);
+    }
+}
+
+void tests (void)
+{
+  static const volatile __flash int32_t vals[] =
+    {
+      0, 1L, -1L, 0x7fffffff, -0x7fffffff, -0x7fffffff - 1,
+      -123456789
+    };
+
+  for (uint8_t i = 0; i < ARRAY_SIZE (vals); ++i)
+    {
+      D x = (D) vals[i];
+      __asm ("" : "+r" (x));
+      if ((int32_t) x != vals[i])
+       __builtin_exit (__LINE__);
+    }
+}
+
+int main (void)
+{
+  testu ();
+  tests ();
+
+  return 0;
+}
+#else
+int main (void)
+{
+  return 0;
+}
+#endif
index bce2dd33e8a269d2dc5ff7324e66ecc0e85b9bae..dc098517ada441b6f0da6596e988e14c4a9280dc 100644 (file)
 #define f7_min __f7_min
 #define f7_max __f7_max
 #define f7_exp10 __f7_exp10
-#define f7_floatunsidf __f7_floatunsidf
-#define f7_floatsidf __f7_floatsidf
 #define f7_extendsfdf2 __f7_extendsfdf2
 #define f7_fixdfsi __f7_fixdfsi
 #define f7_fixdfdi __f7_fixdfdi
index 9033e962ad273545d45dc260568376f14c367b25..169957f50e0294bb7a7aee6ff7e26ea8183f5680 100644 (file)
@@ -135,27 +135,7 @@ _ENDF __truncdfsf2
 #endif /* F7MOD_D_truncdfsf2_ */
 
 ;; Functions that usually live in libgcc: __<name> for <name> in:
-;; floatunsidf floatsidf extendsfdf2
-
-;; double __floatunsidf (type_t)  ; floatunsidf
-#ifdef F7MOD_D_floatunsidf_
-_DEFUN __floatunsidf
-    .global F7_NAME(floatunsidf)
-    ldi     ZH,     hi8(gs(F7_NAME(floatunsidf)))
-    ldi     ZL,     lo8(gs(F7_NAME(floatunsidf)))
-    F7jmp   call_dx
-_ENDF __floatunsidf
-#endif /* F7MOD_D_floatunsidf_ */
-
-;; double __floatsidf (type_t)  ; floatsidf
-#ifdef F7MOD_D_floatsidf_
-_DEFUN __floatsidf
-    .global F7_NAME(floatsidf)
-    ldi     ZH,     hi8(gs(F7_NAME(floatsidf)))
-    ldi     ZL,     lo8(gs(F7_NAME(floatsidf)))
-    F7jmp   call_dx
-_ENDF __floatsidf
-#endif /* F7MOD_D_floatsidf_ */
+;; extendsfdf2
 
 ;; double __extendsfdf2 (type_t)  ; extendsfdf2
 #ifdef F7MOD_D_extendsfdf2_
index a0f9bacf5fe16a04c81fba0e100dcd9cd99e3591..f390eda7385529b129425d130a5ada7a885078cb 100644 (file)
@@ -2201,8 +2201,9 @@ _ENDF __powidf2
 
 ;;; The double exponent starts at bit 52 since the encoded mantissa has 52 bits.
 ;;; Note that when X is a multiple of 16, then dex_lo(x) evaluates to 0.
-#define dex_lo(x) hlo8((x) << (52 - 32))
-#define dex_hi(x) hhi8((x) << (52 - 32))
+#define DEX16(x)  (x) << (52 - 48)
+#define dex_lo(x) lo8 (DEX16 (x))
+#define dex_hi(x) hi8 (DEX16 (x))
 
 #ifdef F7MOD_usa2D_
 _DEFUN __fractusadf
@@ -2388,4 +2389,83 @@ _ENDF __fractdfusa
 #endif /* F7MOD_D2usa_ */
 
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; [u]int32_t -> double conversions.
+
+;; double __floatsidf (int32_t);
+#ifdef F7MOD_D_floatsidf_
+_DEFUN __floatsidf
+    bst     r25, 7
+    brtc    0f
+    XCALL   __negsi2
+0:  XJMP    __floatunsidf.ge0
+_ENDF __floatsidf
+#endif /* F7MOD_D_floatsidf_ */
+
+;; double __floatunsidf (uint32_t);
+#ifdef F7MOD_D_floatunsidf_
+_DEFUN __floatunsidf
+    clt
+_LABEL __floatunsidf.ge0
+    ;; Zero-extend SI at the low end.
+    clr     r18
+    clr     r19
+    wmov    r20,    r18
+    ;; Input is zero?
+    sbiw    r24,    0
+    sbci    r23,    0
+    sbci    r22,    0
+    breq 9f
+    ;; No: The double exponent of 0x80000000 is 31 plus a bias of 1023.
+    ;; Align the SI value such that the MSBit is as R25.4.
+    ;; For each << we have to subtract 1 from the exponent, and for
+    ;; each >> we have to add 1.  Since we want the MSB in R25.4 and
+    ;; not in R25.7, the initial exponent must be reduced by 3.
+    ldi     Xl,     dex_lo (31 + 1023 - 3)
+    ldi     Xh,     dex_hi (31 + 1023 - 3)
+    ;; Move the MSByte to R25.
+1:  tst     r25
+    brne 2f
+    subi    Xl,     dex_lo (8)
+    sbci    Xh,     dex_hi (8)
+    mov     r25,    r24
+    mov     r24,    r23
+    mov     r23,    r22
+    clr     r22
+    rjmp    1b
+2:  ;; Now we have R25 != 0.
+    cpi     r25,    0x20
+    brlo 3f
+    adiw    Xl,     DEX16 (1)
+    lsr     r25
+    ror     r24
+    ror     r23
+    ror     r22
+    ror     r21
+    rjmp 2b
+3:  cpi     r25,    0x10
+    brsh 4f
+    sbiw    Xl,     DEX16 (1)
+    lsl     r22
+    rol     r23
+    rol     r24
+    rol     r25
+    rjmp 3b
+4:  ;; Move the mantissa into place and clear the redundant leading 1.
+    cbr     r25,    0x10
+    mov     r20,    r21
+    mov     r21,    r22
+    mov     r22,    r23
+    mov     r23,    r24
+    mov     r24,    r25
+    ;; Insert the biased exponent.
+    or      r24,    Xl
+    mov     r25,    Xh
+    ;; Insert the sign.
+    bld     r25,    7
+9:  ret
+_ENDF __floatunsidf
+#endif /* F7MOD_D_floatunsidf_ */
+
+
 #endif /* !AVR_TINY */
index 6d35454ee044af29f7d9ad8c126bb0701e07bba9..e2b47409ba808aa7f2a346a218c4fc6584221735 100644 (file)
@@ -36,11 +36,14 @@ F7_ASM_PARTS +=            ha2D uha2D sa2D usa2D
 F7_ASM_PARTS += D2qq D2uqq D2hq D2uhq
 F7_ASM_PARTS +=            D2ha D2uha D2sa D2usa
 
+# Integer -> double conversions
+F7_ASM_PARTS += D_floatsidf D_floatunsidf
+
 # Stuff that will be wrapped in f7-wraps.h (included by libf7-asm.sx)
 # and give f7_asm_D_*.o modules.
 g_ddd += add sub mul div
 g_xdd_cmp +=
-g_dx += floatunsidf floatsidf extendsfdf2
+g_dx += extendsfdf2
 g_xd += fixdfsi fixdfdi fixunsdfdi fixunsdfsi truncdfsf2
 
 m_ddd += pow fmod hypot atan2 fdim
@@ -91,7 +94,7 @@ F7F += set_eps set_1pow2
 
 # Renames for ALIASes without own module.
 F7F += min max exp10
-F7F += floatunsidf floatsidf extendsfdf2
+F7F += extendsfdf2
 F7F += fixdfsi fixdfdi fixunsdfdi fixunsdfsi truncdfsf2
 
 # Renames for f7-const.def.
index 78c218a421bb07276d36b7a25c0de4fe2de67f72..df738b0d5d0ebc0ac6b4c1f58a2cf318ac16b3ad 100644 (file)
@@ -207,7 +207,6 @@ f7_t* f7_set_s32 (f7_t *cc, int32_t i32)
   cc->flags = flags;
   return cc;
 }
-ALIAS (f7_set_s32, f7_floatsidf)
 #endif // F7MOD_set_s32_
 
 
@@ -219,7 +218,6 @@ f7_t* f7_set_u32 (f7_t *cc, uint32_t u32)
   cc->expo = 31;
   return f7_normalize_asm (cc);
 }
-ALIAS (f7_set_u32, f7_floatunsidf)
 #endif // F7MOD_set_u32_