📄 4_1vos
字号:
// c0000610 ;
FC780014 // c0000610 Bt UnImp_OpCd ; continue with opcode analysis
61D80016 // c0000614 MOV R27, R22 ; load Op1 to R27
// c0000618 ;
FC780012 // c0000618 Bt UnImp_OpCd ; continue with opcode analysis
61D80017 // c000061c MOV R27, R23 ; load Op1 to R27
// c0000620 ;
FC780010 // c0000620 Bt UnImp_OpCd ; continue with opcode analysis
0EDE0018 // c0000624 LD.q R27, R24, 24*4 ; load Op1 to R27
// c0000628 ;
FC78000E // c0000628 Bt UnImp_OpCd ; continue with opcode analysis
0EDE0019 // c000062c LD.q R27, R24, 25*4 ; load Op1 to R27
// c0000630 ;
FC78000C // c0000630 Bt UnImp_OpCd ; continue with opcode analysis
0EDE001A // c0000634 LD.q R27, R24, 26*4 ; load Op1 to R27
// c0000638 ;
FC78000A // c0000638 Bt UnImp_OpCd ; continue with opcode analysis
0EDE001B // c000063c LD.q R27, R24, 27*4 ; load Op1 to R27
// c0000640 ;
FC780008 // c0000640 Bt UnImp_OpCd ; continue with opcode analysis
0EDE001C // c0000644 LD.q R27, R24, 28*4 ; load Op1 to R27
// c0000648 ;
FC780006 // c0000648 Bt UnImp_OpCd ; continue with opcode analysis
0EDE001D // c000064c LD.q R27, R24, 29*4 ; load Op1 to R27
// c0000650 ;
FC780004 // c0000650 Bt UnImp_OpCd ; continue with opcode analysis
0EDE001E // c0000654 LD.q R27, R24, 30*4 ; load Op1 to R27
// c0000658 ;
FC780002 // c0000658 Bt UnImp_OpCd ; continue with opcode analysis
0EDE001F // c000065c LD.q R27, R24, 31*4 ; load Op1 to R27
// c0000660 ;------------------------------------------------------------------
// c0000660
// c0000660 ; check opcode (only MUL or DIV possible)
// c0000660 ;DelaySlot LSR R25, R26, 26 ; determine opcode
6A06401E // c0000660 UnImp_OpCd: CMP.f R25, %011110 ; MUL?
FCC00006 // c0000664 Beq.a UnImp_Mul ; branch to MUL routine
61C80000 // c0000668 CLR R25 ; sign positive
6ACE401F // c000066c SUB.f R25, R25, %011111 ; clear R25, DIV?
FCC00023 // c0000670 Beq.a UnImp_Div ; branch to DIV routine
61C80000 // c0000674 CLR R25 ; sign positive
// c0000678 ; opcode was neither MUL nor DIV: hardware error
FF000000 // c0000678 HALT ;
// c000067c
// c000067c
// c000067c ;==================================================================
// c000067c ; signed Multiplication of 32-bit operands by addition
// c000067c ;
// c000067c ; MUL(.f) Rd, Ra, Rb \{REG[Rd|1],REG[Rd&1E]\} := REG[Ra] * REG[Rb]
// c000067c ; MUL(.f) Rd, Ra, IMM \{REG[Rd|1],REG[Rd&1E]\} := REG[Ra] * IMM
// c000067c ;
// c000067c ; local registers:
// c000067c ; R24: pointer to UserSwapSpace to save changed registers
// c000067c ; R25: result sign + manipulations of opcode + SR
// c000067c ; R26: opcode of not implemented instruction
// c000067c ; R27: factor1 (F1) + operand1 of instruction
// c000067c ; R28: high word factor (F2)
// c000067c ; R29: low word factor2 (F2) + operand2 of instruction
// c000067c ; R30: high word result
// c000067c ; R31: low word result
// c000067c ;
// c000067c ;DelaySlot CLR R25 ; result sign positive
// c000067c ;
6B06C000 // c000067c UnImp_Mul: TST.f R27 ; op1 positive?
FC100004 // c0000680 Bpl UnImp_Mul1 ; clear high result register
61F00000 // c0000684 CLR R30 ; otherwise, change
48CE7FFF // c0000688 NOT R25, R25 ; result sign
69D8001B // c000068c NEG R27, R27 ; op1 positive
// c0000690 ;
6B074000 // c0000690 UnImp_Mul1: TST.f R29 ; op2 positive?
FC100004 // c0000694 Bpl UnImp_Mul2 ; clear low result register
61F80000 // c0000698 CLR R31 ; otherwise, change
48CE7FFF // c000069c NOT R25, R25 ; result sign
69E8001D // c00006a0 NEG R29, R29 ; op2 positive
// c00006a4 ;
// c00006a4 ; to optimize performance, ensure the smaller value in the
// c00006a4 ; "shifted" register and F2 > F2
6B07401B // c00006a4 UnImp_Mul2: CMP.f R29, R27 ;
FC280004 // c00006a8 Bge UnImp_Mul3 ; Op2 > Op1?
61E0001D // c00006ac MOV R28, R29 ; exchange values
61E8001B // c00006b0 MOV R29, R27 ;
61D8001C // c00006b4 MOV R27, R28 ;
// c00006b8 ;
61E00000 // c00006b8 UnImp_Mul3: CLR R28 ; clear high F2
// c00006bc ;
// c00006bc ; Product := F2 * F1
// c00006bc ; \{R30,R31\}:=\{R28,R29\}*R27
56DEC001 // c00006bc LSR.f R27, R27, 1 ; if no addition,
FC880005 // c00006c0 UnImp_Mul4: Bcc.a UnImp_Mul5 ; shift
52EF4001 // c00006c4 LSL.f R29, R29, 1 ; low F2
63FFC01D // c00006c8 ADD.f R31, R31, R29 ; otherwise, add low
65F7801C // c00006cc ADDC R30, R30, R28 ; and high and shift
52EF4001 // c00006d0 LSL.f R29, R29, 1 ; shift low F2
65E7001C // c00006d4 UnImp_Mul5: ADDC R28, R28, R28 ; shift high F2 with carry
6B06C000 // c00006d8 TST.f R27 ;
FC87FFF9 // c00006dc Bne.a UnImp_Mul4 ; add again?
56DEC001 // c00006e0 LSR.f R27, R27, 1 ; add next time?
// c00006e4 ;
// c00006e4 ; sign correction necessary?
6B064000 // c00006e4 TST.f R25 ; sign of product
FC90002C // c00006e8 Bpl.a UnImP_Flg1 ;
52068006 // c00006ec LSL.f R00, R26, 6 ;
// c00006f0 ;
6BF8001F // c00006f0 NEG.f R31, R31 ;
FC780028 // c00006f4 Bt UnImp_Flg ; continue with flags
6DF0001E // c00006f8 NEGC R30, R30 ;
// c00006fc ;==================================================================
// c00006fc
// c00006fc
// c00006fc ;==================================================================
// c00006fc ; signed division of 32-bit operands by subtraction
// c00006fc ; R27 : R29 = R30 remainder R31 with 0<=remainder<dividend
// c00006fc ;
// c00006fc ; local registers:
// c00006fc ; R24: pointer to UserSwapSpace to save changed registers
// c00006fc ; R25: sign of result
// c00006fc ; R26: opcode of not implemented instruction
// c00006fc ; R27: divisor
// c00006fc ; R28: position control for shifting
// c00006fc ; R29: divisor
// c00006fc ; R30: integer quotient
// c00006fc ; R31: remainder (and present dividend)
// c00006fc ;
// c00006fc ;DelaySlot CLR R25 ; result sign positive
// c00006fc ;
63F8001B // c00006fc UnImp_Div: MOV.f R31, R27 ; dividend positive?
FC100004 // c0000700 Bpl UnImp_Div1 ; clear high result register
63D8001D // c0000704 MOV.f R27, R29 ;
44CE4002 // c0000708 OR R25, R25, %10 ; change sign
69F8001F // c000070c NEG R31, R31 ; dividend positive
// c0000710 ;
// c0000710 ;DelaySlot MOV.f R27, R29 ; test divisor
FC47FED4 // c0000710 UnImp_Div1: Beq DivByZero ; if 0, branch to exception
61F00000 // c0000714 CLR R30 ; if positive:
FC100005 // c0000718 Bpl UnImp_Div2 ; clear low result register
60E00001 // c000071c MOV R28, 1 ;
44CE4001 // c0000720 OR R25, R25, %01 ; change sign
69E8001D // c0000724 NEG R29, R29 ; divisor positive
61D8001D // c0000728 MOV R27, R29 ; save divisor
// c000072c ;
// c000072c ; shift as required
// c000072c ;DelaySlot MOV R28, 1 ; starting value for position
52EF4001 // c000072c UnImp_Div2: LSL.f R29, R29, 1 ; is divisor*2
FC500004 // c0000730 Bmi UnImp_Div3 ; possible?
6B07C01D // c0000734 CMP.f R31, R29 ; or < dividend?
FCAFFFFD // c0000738 Bge.a UnImp_Div2 ; if yes, continue
50E70001 // c000073c LSL R28, R28, 1 ; and remember new position
54EF4001 // c0000740 UnImp_Div3: LSR R29, R29, 1 ; if no, correction
// c0000744 ;
// c0000744 ;DelaySlot CLR R30 ; initialize quotient
6B07401F // c0000744 CMP.f R29, R31 ; compare divisor and dividend
FCA80005 // c0000748 UnImp_Div4: Bge.a UnImp_Div5 ; divisor greater?
56E70001 // c000074c LSR.f R28, R28, 1 ; if yes, correct position
69FFC01D // c0000750 SUB R31, R31, R29 ; if no, subtract divisor
61F7801C // c0000754 ADD R30, R30, R28 ; and update quotient
56E70001 // c0000758 LSR.f R28, R28, 1 ; and shift position right
54EF4001 // c000075c UnImp_Div5: LSR R29, R29, 1 ; and divisor
FC87FFFA // c0000760 Bne.a UnImp_Div4 ; if not done,
6B07401F // c0000764 CMP.f R29, R31 ; compare divisor and dividend
// c0000768 ;
// c0000768 ; correct result due to sign?
6A064000 // c0000768 CMP.f R25, %00 ; (+) : (+) ?
FC40000A // c000076c Beq UnImP_Flg ; if yes, no correction
6A064001 // c0000770 CMP.f R25, %01 ; if no: (+) : (-) ?
FC400007 // c0000774 Beq UnImp_Div7 ; if yes, negate quotient
6B00001F // c0000778 NEG.f R00, R31 ; remainder 0 (or "negative")?
FC400003 // c000077c Beq UnImp_Div6 ; 0, test if correction
65F78000 // c0000780 ADDC R30, R30, R00 ; negative, increase quotient
69FEC01F // c0000784 SUB R31, R27, R31 ; correct remainder
6A064002 // c0000788 UnImp_Div6: CMP.f R25, %10 ; (-) : (+) ?
FCC00002 // c000078c Beq.a UnImP_Flg ; if yes,
69F0001E // c0000790 UnImp_Div7: NEG R30, R30 ; negate quotient
// c0000794 ;==================================================================
// c0000794
// c0000794
// c0000794 ; test if flags have to be set
52068006 // c0000794 UnImP_Flg: LSL.f R00, R26, 6 ; flag option?
FC10000A // c0000798 UnImP_Flg1: Bpl UnImp_Rd ; if no, compute Rd REG no
6B078000 // c000079c TST.f R30 ; otherwise, set flags
FCC00002 // c00007a0 Beq.a UnImp_Flg2 ; if high=0,
6B07C000 // c00007a4 TST.f R31 ; check low result
EAE0C000 // c00007a8 UnImp_Flg2: LRFS R28, SR ; load NZVC flags from SR
40E7000F // c00007ac AND R28, R28, %00001111 ;
EAE9C000 // c00007b0 LRFS R29, ECSR ; combine status
40EF40F0 // c00007b4 AND R29, R29, %11110000 ; from ECSR
45EF401C // c00007b8 OR R29, R29, R28 ; with flags
EB38001D // c00007bc SRIS ECSR, R29 ; and transfer
// c00007c0
// c00007c0 ; determine destination
50CE8008 // c00007c0 UnImp_Rd: LSL R25, R26, 8 ; compute
54CE401C // c00007c4 LSR R25, R25, 28 ; destination
50CE4004 // c00007c8 LSL R25, R25, 4 ; and
E0DE0000 // c00007cc LDH R27, UnImp_RdTb ; add to
44DEC7E0 // c00007d0 OR R27, R27, UnImp_RdTb & $1FFF ; branch table
61DEC019 // c00007d4 ADD R27, R27, R25 ; as distance
EB00001B // c00007d8 JMP R27 ; store result
EAC8C000 // c00007dc LRFS R25, SR ;
// c00007e0 ;------------------------------------------------------------------
// c00007e0 ; branch tab
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -