1 // Externe Routinen zu ARILEV1.D
2 // Prozessor: HPPA, wegen XMPYU nur auf HPPA 1.1 (etwa HP9000/720)
3 // Compiler: GNU-C oder HP-C
4 // Parameter-Übergabe: in Registern %arg0,%arg1,%arg2, Rückgabewert in %ret0.
5 // Einstellungen: intCsize=32, intDsize=32.
7 // Großenteils abgeschrieben von hppa.s aus der PARI/GP-Distribution.
15 // Liefert integer-size (>=1, <=32) des Arguments /=0.
18 .ENTER // Input in %arg0, Output in %ret0
21 // if (x & (bit(31-15)*(bit(16)-1)) == 0)
22 EXTRU,<> %arg0,15,16,%r0
23 SHD,TR %arg0,%r0,16,%arg0 // x = x<<(32-16); else
24 ADDI 16,%ret0,%ret0 // y = y+16;
25 // if (x & (bit(31-7)*(bit(8)-1)) == 0)
26 EXTRU,<> %arg0,7,8,%r0
27 SHD,TR %arg0,%r0,24,%arg0 // x = x<<(32-24); else
28 ADDI 8,%ret0,%ret0 // y = y+8;
29 // if (x & (bit(31-3)*(bit(4)-1)) == 0)
30 EXTRU,<> %arg0,3,4,%r0
31 SHD,TR %arg0,%r0,28,%arg0 // x = x<<(32-28); else
32 ADDI 4,%ret0,%ret0 // y = y+4;
33 // if (x & (bit(31-1)*(bit(2)-1)) == 0)
34 EXTRU,<> %arg0,1,2,%r0
35 SHD,TR %arg0,%r0,30,%arg0 // x = x<<(32-30); else
36 ADDI 2,%ret0,%ret0 // y = y+2;
37 // if (x & (bit(31-0)*(bit(1)-1)) != 0)
39 ADDI 1,%ret0,%ret0 // y = y+1;
44 #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
49 mulu32_high .WORD // 8 Byte Platz
54 // extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
55 // 2^32*hi+lo := arg1*arg2.
58 .ENTER // Input in %arg0,%arg1, Output in %ret0,mulu32_high
59 LDIL L'mulu32_high-$global$,%r1
60 LDO R'mulu32_high-$global$(%r1),%r1
62 STW %arg0,0(%r1) // x abspeichern
63 FLDWS 0(%r1),%fr4 // und in den Coprozessor laden
64 STW %arg1,0(%r1) // y abspeichern
65 FLDWS 0(%r1),%fr5 // und in den Coprozessor laden
66 XMPYU %fr4,%fr5,%fr6 // beides multiplizieren
67 FSTDS %fr6,0(%r1) // Ergebnis (64 Bit) abspeichern
68 LDWS 4(%r1),%ret0 // low 32 Bit als Ergebnis