PDA

View Full Version : Prodotto tra interi a 64bit


Titti92
25-05-2016, 19:45
Sto utilizzando Assembly MIPS, ma la mia è una domanda più che altro di carattere generale. Devo fare il prodotto tra due interi a 64 bit, quindi salvati ciascuno in due registri a 32bit (facciamo per esempio che uno sia in $a0,$a1 e l'altro in $a2,$a3, dove il numero del registro più basso indica che vi è la parte meno significativa del numero). So che per trovare il prodotto devo fare:
$v0=LO(a0*a3)
$v1=HI(a0*a2)+LO(a1*a2)+LO(a0*a3)
dove HI e LO sono due registri di appoggio utilizzati dall'istruzione MULT (prodotto tra deu reg. a 32 bit) del Mips, quindi in HI ci va la parte alta del prodotto e in LO la parte bassa. E' giusto quello che ho detto? E se sì, mi potete spiegare perché? Dovrei fare anche il prodotto tra interi a 64 e riportarlo a 128 bito quindi vorrei capire come funziona questo primo prodotto.

Titti92
27-05-2016, 14:02
nessuno?

cdimauro
27-05-2016, 18:35
Non conosco adeguatamente l'architettura MIPS, ma probabilmente con questo risolvi: https://bytes.com/topic/c/answers/216221-32x32-64x64-signed-integer-multiplication

Titti92
29-05-2016, 14:46
Grazie! Comunque la mia è una domanda un po' generica, non proprio soltanto dell'archtettura MIPS.

cdimauro
29-05-2016, 18:26
OK, allora potresti spiegare prima cosa intendi con questo:

LO(a0*a3)

?

Se LO è un registro che contiene la parte bassa del risultato di una moltiplicazione, non capisco che ruolo abbia nell'espressione che hai usato, visto che a0*a3 dovrebbe rappresentare il prodotto di quei due registri.

Titti92
15-06-2016, 09:02
OK, allora potresti spiegare prima cosa intendi con questo:

LO(a0*a3)

?

Se LO è un registro che contiene la parte bassa del risultato di una moltiplicazione, non capisco che ruolo abbia nell'espressione che hai usato, visto che a0*a3 dovrebbe rappresentare il prodotto di quei due registri.
L'operazione di moltiplicazione restituisce un numero a 64 bit, diviso su due registri a 32 bit: LO e HI, il primo contiene la parte bassa del risultato e l'altro la parte alta. Con LO(a0*a3) intendevo dire che prendo la parte bassa di quel prodotto.

cdimauro
15-06-2016, 20:04
OK. Allora partiamo dallo pseudocodice di quello che devi eseguire. Ho trovato un post semplice qui (https://www.dsprelated.com/showthread/comp.dsp/89790-1.php) che descrive la classica operazione di moltiplicazione a precisione più elevata, sfruttando 4 istruzioni di moltiplicazione a metà precisione:
A2A1
x B2B1
----------
B1A1
+ B1A2
+ B2A1
+ B2A2
----------
C4C3C2C1
Alla fine ho aggiunto degli pseudoregistri anche per i 4 valori a 32-bit che conterranno il valore a 128-bit prodotto dall'operazione, in modo da rendere visivamente dove andranno a finire i risultati parziali.

Supponendo che siano tutti registri a 32-bit, B1A1 lo devi tradurre nell'istruzione MIPS di moltiplicazione 32x32 (senza segno), che produrrà i risultati in LO e HI.

Al primo passo semplicemente li conserverai LO in C1 (che rimarrà tale) e HI in C2, mentre mettera che devono contenere il risultato finale, a 128-bit, dell'operazione di moltiplicazione.

Per il secondo passo ti consiglierei di calcolare B2A2, copiando poi LO in C3 e HI in C4.

A questo punto devi eseguire i due prodotti intermedi, e sommare i risultati a C2 con somma semplice, a C3 con somma con riporto (che può provenire dalla precedente somma), e sommare zero + riporto (che può provenire dalla precedente somma) a C4.

Penso sia tutto. Ovviamente la stessa cosa vale per la moltiplicazione 128x128 -> 256 bit.

Titti92
20-06-2016, 08:04
OK. Allora partiamo dallo pseudocodice di quello che devi eseguire. Ho trovato un post semplice qui (https://www.dsprelated.com/showthread/comp.dsp/89790-1.php) che descrive la classica operazione di moltiplicazione a precisione più elevata, sfruttando 4 istruzioni di moltiplicazione a metà precisione:
A2A1
x B2B1
----------
B1A1
+ B1A2
+ B2A1
+ B2A2
----------
C4C3C2C1
Alla fine ho aggiunto degli pseudoregistri anche per i 4 valori a 32-bit che conterranno il valore a 128-bit prodotto dall'operazione, in modo da rendere visivamente dove andranno a finire i risultati parziali.

Supponendo che siano tutti registri a 32-bit, B1A1 lo devi tradurre nell'istruzione MIPS di moltiplicazione 32x32 (senza segno), che produrrà i risultati in LO e HI.

Al primo passo semplicemente li conserverai LO in C1 (che rimarrà tale) e HI in C2, mentre mettera che devono contenere il risultato finale, a 128-bit, dell'operazione di moltiplicazione.

Per il secondo passo ti consiglierei di calcolare B2A2, copiando poi LO in C3 e HI in C4.

A questo punto devi eseguire i due prodotti intermedi, e sommare i risultati a C2 con somma semplice, a C3 con somma con riporto (che può provenire dalla precedente somma), e sommare zero + riporto (che può provenire dalla precedente somma) a C4.

Penso sia tutto. Ovviamente la stessa cosa vale per la moltiplicazione 128x128 -> 256 bit.
Grazie mille!