어셈블리프로그램 설계 및 실습 Lab #8 Floating-point number - Multiplication Teaching assistants Jiwoon Lee jwlee@linux.com Jeongwon Hwang jeong202192@kw.ac.kr 학습목표 • Arm에는 floating point를 해주는 instruction이 존재하지 않는다. 때문에 floating point가 입력되었을 때 해당연산을 수행시켜주는 assembly code가 필요하다. • Floating point의 multiplier를 구현하여 floating point의 곱셈에 대하여 알아보자 • Normalize과정에서 어떤 경우에는 right로, 어떤 경우에는 left로 shift되는지를 고려하며 코드를 작성하여 보자 Floating-Point • IEEE 754 Floating-Point Format S Exponent Mantissa 1-bit e-bits m-bits - Value = (−1)𝑠 × (1. 𝑚𝑎𝑛𝑡𝑖𝑠𝑠𝑎) × 2(𝑒𝑥𝑝𝑜𝑛𝑒𝑛𝑡−127) (for float32) - Precisions Half-precision - 16-bits notation : e=5, m=10 Single-precision – 32-bits notation : e=8, m=23 Double-precision – 64-bits notation : e=11, m=52 Floating-Point Number • Special Cases - x: don’t care - 010 x 0000 0000 0000 1-bit e-bits 000 0000 0000 0000 0000 0 1111 1111 0000 1-bit e-bits 000 0000 0000 0000 0000 1 1111 1111 0000 1-bit e-bits 000 0000 0000 0000 0000 m-bits - ∞ m-bits - -∞ - Nan x 1111 1111 1-bit e-bits m-bits non-zero m-bits Example • 120.75 * -14.25 (Expected result: -1720.6875) 120.75 = 0x42F18000 -14.25 = 0xC1640000 0 10000101 111 0001 1000 0000 0000 0000 1 10000010 110 0100 0000 0000 0000 0000 - 120.7510 = 111 1000.112 -> exp: 133 (정규화: 1.111000112 × 26 ) - −14.2510 = −1110.012 -> exp: 130 (정규화: −1.110012 × 23 ) 1. Sign 비교 - Sign이 같은 경우 => 양수 (양수 * 양수 또는 음수 * 음수) - Sign이 다른 경우 => 음수 (양수 * 음수 또는 음수 * 양수) 2. Exponent끼리 더한 후 Bias 뺄셈 (Single precision의 경우 Bias=127) - 133 + 130 – bias = 136 Example • 120.75 * -14.25 (Expected result: -1720.6875) 120.75 = 0x42F18000 -14.25 = 0xC1640000 0 10000101 111 0001 1000 0000 0000 0000 1 10000010 110 0100 0000 0000 0000 0000 - 120.7510 = 111 1000.112 -> exp: 133 (정규화: 1.111000112 × 26 ) - −14.2510 = −1110.012 3. Mantissa 곱셈 -> exp: 130 (정규화: −1.110012 × 23 ) Example • 120.75 * -14.25 (Expected result: -1720.6875) 120.75 = 0x42F18000 -14.25 = 0xC1640000 0 10000101 111 0001 1000 0000 0000 0000 1 10000010 110 0100 0000 0000 0000 0000 - 120.7510 = 111 1000.112 -> exp: 133 (정규화: 1.111000112 × 26 ) - −14.2510 = −1110.012 -> exp: 130 (정규화: −1.110012 × 23 ) 8자리 +5자리 4. 소수부 자릿수 계산 13자리 Example • 120.75 * -14.25 (Expected result: -1720.6875) 120.75 = 0x42F18000 -14.25 = 0xC1640000 0 10000101 111 0001 1000 0000 0000 0000 1 10000010 110 0100 0000 0000 0000 0000 - 120.7510 = 111 1000.112 -> exp: 133 (정규화: 1.111000112 × 26 ) - −14.2510 = −1110.012 -> exp: 130 (정규화: −1.110012 × 23 ) 5. Normalize - −1.101011100010112 × 2137−𝑏𝑖𝑎𝑠 6. HEX로 표시 - 1 10001001 101 0111 0001 0110 0000 0000 - 0xC4D71600 - -1720.6875 Instruction • UMULL{cond} RdHi, RdLo, Rm, Rs - Rm에 저장된 값과 Rs값을 곱하여 RdHi, RdLo에 저장 - RdHi에는 연산 결과의 상위 32비트, RdLo에는 하위 32비트 저장됨 - Rd는 Rm과 같을 수 없음 - Mantissa를 곱할 때 MUL 명령어를 이용하여 계산 가능 • LSL #number - Number 만큼 왼쪽으로 bit stream을 shift • 어떻게 하면 32비트에서 sign, exponent, mantissa를 추출할 수 있을까? 1. Bit masking -> 구현이 간단할 수 있음 -> 메모리 액세스 시간 증가 2. Shift 연산 - Ex) mov r0,#2; mov r0,r0,LSL #2 ➔r0 = 2*4 = 8 • LSR #number - Number만큼 오른쪽으로 bit stream을 shift - Ex) mov r0,#8; mov r0,r0,LSR #2 ➔ r0 = 8/4 = 2 -> Logical shift left/right를 통해 특정 비트만 추출 -> 구현 난이도가 복잡하지는 않지만, 1번보다는 복잡할 수 있음 -> 메모리 액세스가 bit masking보다 적음 (memory가 아닌 shifter 이용)