die 64-Bit Prozessoren bieten ja eine 64Bit * 64Bit Multiplikation mit 128Bit Ergebnis,
gibt es in C keinen Zugriff darauf? ( SuSE Linux 11.4 )
die 64-Bit Prozessoren bieten ja eine 64Bit * 64Bit Multiplikation mit 128Bit Ergebnis,
gibt es in C keinen Zugriff darauf? ( SuSE Linux 11.4 )
mit extended Inline-Assembly (gcc syntax) kein Problem:
Code:#include <stdio.h> int main(void) { unsigned long long upper = 0, lower = 0; unsigned long long a = 1ULL<<32; unsigned long long b = 1ULL<<32; // multiply asm("movq %2, %%rax\n" "movq %3, %%rdx\n" "mul %%rdx\n" "movq %%rax, %1\n" "movq %%rdx, %0" : "=r"(upper), "=r"(lower) /* output */ : "r"(a), "r"(b) /* input */ : "%rax", "%rdx" /* clobbered regs */ ); printf("0x%llx 0x%llx\n", upper, lower); // gibt "0x1 0x0" aus return 0; }
schön, nach Durchlesen des "Inline-Assembly-HOWTO's" hab ich's auch einigermaßen verstanden,
aber wie schafft man nun eine "inline function" die beim Aufruf dann wirklich als nur 2 Befehle compiliert
wird und auch wie beabsichtigt funktioniert?
Was
muß im folgenden an stelle der Fragezeichen stehen?
#include <stdio.h>
typedef unsigned long long tU64;
typedef struct {tU64 lw; tU64 hi;} tU128;
inline
tU128 m128(tU64 f1, tU64 f2)
__attribute__((always_inline));
inline
tU128 m128(tU64 f1,tU64 f2){
asm("movq %?,%%rax\n"
"mulq %?"
:?
:"m"(f1),"m"(f2)
);
}
int main(){
tU64 a,b; tU128 p;
scanf("%llu%llu",&a,&b);
p = m128(a,b);
printf("%llu %llu\n",p.lw,p.hi);
return 0;
}
0) Bitte [code] tags verwenden
1) Das Ganze von Hand in assembly schreiben wenn's wirklich auf ein paar Instruktionen mehr oder weniger ankommt.
2) im C-Fileeinfügen und ein zweites File mul.sCode:extern tU128 mul128(tU64 f1, tU64 f2);mitkompilieren. Bei dieser Methode verlierst du allerdings die Möglichkeit die Multiplikation zu inlinen.Code:# args: # uint64_t a in %rdi # uint64_t b in %rsi # this conforms to the Linux amd64 abi # # result: %rdi*%rsi in %rax:%rdx # --> handles as struct { uint64_t lo, uint64_t hi } in C .global mul128 mul128: push %rbp movq %rsp, %rbp movq %rdi, %rax mulq %rsi leave ret
HTH
-- jeebee
Danke, jeebee;
schade;
Lösung 2 hatte ich selbst schon, allerdings scheint (direkt mit as als .o übersetzt)
zu genügen - oder sind da Probleme zu erwarten?Code:.section .text .type Mul128 , @function .globl Mul128 Mul128: movq %rdi,%rax mulq %rsi ret .end
im übrigem eigentlich ein Compilermangel - oder gibt's 64-Bitprozessoren die bei einer
64Bit Mult. kein 128Bit ergebnis liefern?
Das sollte in diesem Fall genügen.
Es ist kein Compilermangel, da dasselbe C-Programm auch auf einer 32bit Architektur übersetzt werden könnte (da hast du dann keine Multiplikation mit 128bit Resultat).
Lesezeichen