summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/main.cpp4
-rw-r--r--src/core/arm/interpreter/armemu.cpp276
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp476
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h9
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpdouble.cpp2055
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpsingle.cpp1944
-rw-r--r--src/core/hle/service/srv.cpp2
7 files changed, 2626 insertions, 2140 deletions
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index bac6a6bb8..153712273 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -128,10 +128,10 @@ GMainWindow::~GMainWindow()
128 128
129void GMainWindow::BootGame(std::string filename) 129void GMainWindow::BootGame(std::string filename)
130{ 130{
131 NOTICE_LOG(MASTER_LOG, "citra starting...\n"); 131 NOTICE_LOG(MASTER_LOG, "Citra starting...\n");
132 132
133 if (Core::Init()) { 133 if (Core::Init()) {
134 ERROR_LOG(MASTER_LOG, "core initialization failed, exiting..."); 134 ERROR_LOG(MASTER_LOG, "Core initialization failed, exiting...");
135 Core::Stop(); 135 Core::Stop();
136 exit(1); 136 exit(1);
137 } 137 }
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index cdcf47ee1..73223874e 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -63,13 +63,6 @@ static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int);
63static void Handle_Load_Double (ARMul_State *, ARMword); 63static void Handle_Load_Double (ARMul_State *, ARMword);
64static void Handle_Store_Double (ARMul_State *, ARMword); 64static void Handle_Store_Double (ARMul_State *, ARMword);
65 65
66void
67XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far);
68int
69XScale_debug_moe (ARMul_State * state, int moe);
70unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
71 unsigned cpnum);
72
73static int 66static int
74handle_v6_insn (ARMul_State * state, ARMword instr); 67handle_v6_insn (ARMul_State * state, ARMword instr);
75 68
@@ -376,7 +369,7 @@ ARMul_Emulate26 (ARMul_State * state)
376#endif 369#endif
377{ 370{
378 /* The PC pipeline value depends on whether ARM 371 /* The PC pipeline value depends on whether ARM
379 or Thumb instructions are being 372 or Thumb instructions are being
380 d. */ 373 d. */
381 ARMword isize; 374 ARMword isize;
382 ARMword instr; /* The current instruction. */ 375 ARMword instr; /* The current instruction. */
@@ -538,6 +531,7 @@ ARMul_Emulate26 (ARMul_State * state)
538 state->AbortAddr = 1; 531 state->AbortAddr = 1;
539 532
540 instr = ARMul_LoadInstrN (state, pc, isize); 533 instr = ARMul_LoadInstrN (state, pc, isize);
534
541 //chy 2006-04-12, for ICE debug 535 //chy 2006-04-12, for ICE debug
542 have_bp=ARMul_ICE_debug(state,instr,pc); 536 have_bp=ARMul_ICE_debug(state,instr,pc);
543#if 0 537#if 0
@@ -562,6 +556,7 @@ ARMul_Emulate26 (ARMul_State * state)
562 } 556 }
563 printf("\n"); 557 printf("\n");
564#endif 558#endif
559
565 instr = ARMul_LoadInstrN (state, pc, isize); 560 instr = ARMul_LoadInstrN (state, pc, isize);
566 state->last_instr = state->CurrInstr; 561 state->last_instr = state->CurrInstr;
567 state->CurrInstr = instr; 562 state->CurrInstr = instr;
@@ -952,9 +947,8 @@ ARMul_Emulate26 (ARMul_State * state)
952 case t_decoded: 947 case t_decoded:
953 /* ARM instruction available. */ 948 /* ARM instruction available. */
954 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); 949 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp);
955 950
956 if (armOp == 0xDEADC0DE) 951 if (armOp == 0xDEADC0DE) {
957 {
958 DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc); 952 DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc);
959 } 953 }
960 954
@@ -967,7 +961,6 @@ ARMul_Emulate26 (ARMul_State * state)
967 } 961 }
968 } 962 }
969#endif 963#endif
970
971 /* Check the condition codes. */ 964 /* Check the condition codes. */
972 if ((temp = TOPBITS (28)) == AL) { 965 if ((temp = TOPBITS (28)) == AL) {
973 /* Vile deed in the need for speed. */ 966 /* Vile deed in the need for speed. */
@@ -1124,6 +1117,7 @@ ARMul_Emulate26 (ARMul_State * state)
1124 1117
1125//chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it... 1118//chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it...
1126 1119
1120
1127 /* Actual execution of instructions begins here. */ 1121 /* Actual execution of instructions begins here. */
1128 /* If the condition codes don't match, stop here. */ 1122 /* If the condition codes don't match, stop here. */
1129 if (temp) { 1123 if (temp) {
@@ -2308,12 +2302,9 @@ mainswitch:
2308 if (state->Aborted) { 2302 if (state->Aborted) {
2309 TAKEABORT; 2303 TAKEABORT;
2310 } 2304 }
2311 if (enter) 2305 if (enter) {
2312 {
2313 state->Reg[DESTReg] = 0; 2306 state->Reg[DESTReg] = 0;
2314 } 2307 } else {
2315 else
2316 {
2317 state->Reg[DESTReg] = 1; 2308 state->Reg[DESTReg] = 1;
2318 } 2309 }
2319 break; 2310 break;
@@ -3063,7 +3054,27 @@ mainswitch:
3063 break; 3054 break;
3064 3055
3065 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ 3056 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
3066 if (BIT (4)) { 3057 //ichfly PKHBT PKHTB todo check this
3058 if ((instr & 0x70) == 0x10) //pkhbt
3059 {
3060 u8 idest = BITS(12, 15);
3061 u8 rfis = BITS(16, 19);
3062 u8 rlast = BITS(0, 3);
3063 u8 ishi = BITS(7,11);
3064 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
3065 break;
3066 }
3067 else if ((instr & 0x70) == 0x50)//pkhtb
3068 {
3069 u8 idest = BITS(12, 15);
3070 u8 rfis = BITS(16, 19);
3071 u8 rlast = BITS(0, 3);
3072 u8 ishi = BITS(7, 11);
3073 if (ishi == 0)ishi = 0x20;
3074 state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000);
3075 break;
3076 }
3077 else if (BIT (4)) {
3067#ifdef MODE32 3078#ifdef MODE32
3068 if (state->is_v6 3079 if (state->is_v6
3069 && handle_v6_insn (state, instr)) 3080 && handle_v6_insn (state, instr))
@@ -3675,7 +3686,13 @@ mainswitch:
3675 3686
3676 /* Co-Processor Data Transfers. */ 3687 /* Co-Processor Data Transfers. */
3677 case 0xc4: 3688 case 0xc4:
3678 if (state->is_v5) { 3689 if ((instr & 0x0FF00FF0) == 0xC400B10) //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0
3690 {
3691 state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
3692 state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
3693 break;
3694 }
3695 else if (state->is_v5) {
3679 /* Reading from R15 is UNPREDICTABLE. */ 3696 /* Reading from R15 is UNPREDICTABLE. */
3680 if (BITS (12, 15) == 15 || BITS (16, 19) == 15) 3697 if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
3681 ARMul_UndefInstr (state, instr); 3698 ARMul_UndefInstr (state, instr);
@@ -3695,13 +3712,21 @@ mainswitch:
3695 break; 3712 break;
3696 3713
3697 case 0xc5: 3714 case 0xc5:
3698 if (state->is_v5) { 3715 if ((instr & 0x00000FF0) == 0xB10) //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0
3716 {
3717 state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
3718 state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
3719 break;
3720 }
3721 else if (state->is_v5) {
3699 /* Writes to R15 are UNPREDICATABLE. */ 3722 /* Writes to R15 are UNPREDICATABLE. */
3700 if (DESTReg == 15 || LHSReg == 15) 3723 if (DESTReg == 15 || LHSReg == 15)
3701 ARMul_UndefInstr (state, instr); 3724 ARMul_UndefInstr (state, instr);
3702 /* Is access to the coprocessor allowed ? */ 3725 /* Is access to the coprocessor allowed ? */
3703 else if (!CP_ACCESS_ALLOWED(state, CPNum)) 3726 else if (!CP_ACCESS_ALLOWED(state, CPNum))
3704 ARMul_UndefInstr (state, instr); 3727 {
3728 ARMul_UndefInstr(state, instr);
3729 }
3705 else { 3730 else {
3706 /* MRRC, ARMv5TE and up */ 3731 /* MRRC, ARMv5TE and up */
3707 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); 3732 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
@@ -4059,9 +4084,11 @@ TEST_EMULATE:
4059 // continue; 4084 // continue;
4060 else if (state->Emulate != RUN) 4085 else if (state->Emulate != RUN)
4061 break; 4086 break;
4062 } 4087
4063 while (state->NumInstrsToExecute--); 4088 }
4064 4089
4090 while (state->NumInstrsToExecute);
4091exit:
4065 state->decoded = decoded; 4092 state->decoded = decoded;
4066 state->loaded = loaded; 4093 state->loaded = loaded;
4067 state->pc = pc; 4094 state->pc = pc;
@@ -5686,12 +5713,98 @@ L_stm_s_takeabort:
5686 case 0x3f: 5713 case 0x3f:
5687 printf ("Unhandled v6 insn: rbit\n"); 5714 printf ("Unhandled v6 insn: rbit\n");
5688 break; 5715 break;
5716#endif
5689 case 0x61: 5717 case 0x61:
5690 printf ("Unhandled v6 insn: sadd/ssub\n"); 5718 if ((instr & 0xFF0) == 0xf70)//ssub16
5719 {
5720 u8 tar = BITS(12, 15);
5721 u8 src1 = BITS(16, 19);
5722 u8 src2 = BITS(0, 3);
5723 s16 a1 = (state->Reg[src1] & 0xFFFF);
5724 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5725 s16 b1 = (state->Reg[src2] & 0xFFFF);
5726 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5727 state->Reg[tar] = (a1 - a2)&0xFFFF | (((b1 - b2)&0xFFFF)<< 0x10);
5728 return 1;
5729 }
5730 else if ((instr & 0xFF0) == 0xf10)//sadd16
5731 {
5732 u8 tar = BITS(12, 15);
5733 u8 src1 = BITS(16, 19);
5734 u8 src2 = BITS(0, 3);
5735 s16 a1 = (state->Reg[src1] & 0xFFFF);
5736 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5737 s16 b1 = (state->Reg[src2] & 0xFFFF);
5738 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5739 state->Reg[tar] = (a1 + a2)&0xFFFF | (((b1 + b2)&0xFFFF)<< 0x10);
5740 return 1;
5741 }
5742 else if ((instr & 0xFF0) == 0xf50)//ssax
5743 {
5744 u8 tar = BITS(12, 15);
5745 u8 src1 = BITS(16, 19);
5746 u8 src2 = BITS(0, 3);
5747 s16 a1 = (state->Reg[src1] & 0xFFFF);
5748 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5749 s16 b1 = (state->Reg[src2] & 0xFFFF);
5750 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5751 state->Reg[tar] = (a1 - b2) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10);
5752 return 1;
5753 }
5754 else if ((instr & 0xFF0) == 0xf30)//sasx
5755 {
5756 u8 tar = BITS(12, 15);
5757 u8 src1 = BITS(16, 19);
5758 u8 src2 = BITS(0, 3);
5759 s16 a1 = (state->Reg[src1] & 0xFFFF);
5760 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5761 s16 b1 = (state->Reg[src2] & 0xFFFF);
5762 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5763 state->Reg[tar] = (a2 - b1) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10);
5764 return 1;
5765 }
5766 else printf ("Unhandled v6 insn: sadd/ssub\n");
5691 break; 5767 break;
5692 case 0x62: 5768 case 0x62:
5693 printf ("Unhandled v6 insn: qadd/qsub\n"); 5769 if ((instr & 0xFF0) == 0xf70)//QSUB16
5770 {
5771 u8 tar = BITS(12, 15);
5772 u8 src1 = BITS(16, 19);
5773 u8 src2 = BITS(0, 3);
5774 s16 a1 = (state->Reg[src1] & 0xFFFF);
5775 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5776 s16 b1 = (state->Reg[src2] & 0xFFFF);
5777 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5778 s32 res1 = (a1 - b1);
5779 s32 res2 = (a2 - b2);
5780 if (res1 > 0x7FFF) res1 = 0x7FFF;
5781 if (res2 > 0x7FFF) res2 = 0x7FFF;
5782 if (res1 < 0x7FFF) res1 = -0x8000;
5783 if (res2 < 0x7FFF) res2 = -0x8000;
5784 state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10);
5785 return 1;
5786 }
5787 else if ((instr & 0xFF0) == 0xf10)//QADD16
5788 {
5789 u8 tar = BITS(12, 15);
5790 u8 src1 = BITS(16, 19);
5791 u8 src2 = BITS(0, 3);
5792 s16 a1 = (state->Reg[src1] & 0xFFFF);
5793 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5794 s16 b1 = (state->Reg[src2] & 0xFFFF);
5795 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5796 s32 res1 = (a1 + b1);
5797 s32 res2 = (a2 + b2);
5798 if (res1 > 0x7FFF) res1 = 0x7FFF;
5799 if (res2 > 0x7FFF) res2 = 0x7FFF;
5800 if (res1 < 0x7FFF) res1 = -0x8000;
5801 if (res2 < 0x7FFF) res2 = -0x8000;
5802 state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10);
5803 return 1;
5804 }
5805 else printf ("Unhandled v6 insn: qadd/qsub\n");
5694 break; 5806 break;
5807#if 0
5695 case 0x63: 5808 case 0x63:
5696 printf ("Unhandled v6 insn: shadd/shsub\n"); 5809 printf ("Unhandled v6 insn: shadd/shsub\n");
5697 break; 5810 break;
@@ -5709,10 +5822,65 @@ L_stm_s_takeabort:
5709 break; 5822 break;
5710#endif 5823#endif
5711 case 0x6c: 5824 case 0x6c:
5712 printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); 5825 if ((instr & 0xf03f0) == 0xf0070) //uxtb16
5826 {
5827 u8 src1 = BITS(0, 3);
5828 u8 tar = BITS(12, 15);
5829 u32 base = state->Reg[src1];
5830 u32 shamt = BITS(9,10)* 8;
5831 u32 in = ((base << (32 - shamt)) | (base >> shamt));
5832 state->Reg[tar] = in & 0x00FF00FF;
5833 return 1;
5834 }
5835 else
5836 printf ("Unhandled v6 insn: uxtb16/uxtab16\n");
5713 break; 5837 break;
5714 case 0x70: 5838 case 0x70:
5715 printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); 5839 if ((instr & 0xf0d0) == 0xf010)//smuad //ichfly
5840 {
5841 u8 tar = BITS(16, 19);
5842 u8 src1 = BITS(0, 3);
5843 u8 src2 = BITS(8, 11);
5844 u8 swap = BIT(5);
5845 s16 a1 = (state->Reg[src1] & 0xFFFF);
5846 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5847 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5848 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5849 state->Reg[tar] = a1*a2 + b1*b2;
5850 return 1;
5851
5852 }
5853 else if ((instr & 0xf0d0) == 0xf050)//smusd
5854 {
5855 u8 tar = BITS(16, 19);
5856 u8 src1 = BITS(0, 3);
5857 u8 src2 = BITS(8, 11);
5858 u8 swap = BIT(5);
5859 s16 a1 = (state->Reg[src1] & 0xFFFF);
5860 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5861 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5862 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5863 state->Reg[tar] = a1*a2 - b1*b2;
5864 return 1;
5865 }
5866 else if ((instr & 0xd0) == 0x10)//smlad
5867 {
5868 u8 tar = BITS(16, 19);
5869 u8 src1 = BITS(0, 3);
5870 u8 src2 = BITS(8, 11);
5871 u8 src3 = BITS(12, 15);
5872 u8 swap = BIT(5);
5873
5874 u32 a3 = state->Reg[src3];
5875
5876 s16 a1 = (state->Reg[src1] & 0xFFFF);
5877 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5878 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5879 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5880 state->Reg[tar] = a1*a2 + b1*b2 + a3;
5881 return 1;
5882 }
5883 else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n");
5716 break; 5884 break;
5717 case 0x74: 5885 case 0x74:
5718 printf ("Unhandled v6 insn: smlald/smlsld\n"); 5886 printf ("Unhandled v6 insn: smlald/smlsld\n");
@@ -5750,13 +5918,10 @@ L_stm_s_takeabort:
5750 if (state->Aborted) { 5918 if (state->Aborted) {
5751 TAKEABORT; 5919 TAKEABORT;
5752 } 5920 }
5753 5921
5754 if (enter) 5922 if (enter) {
5755 {
5756 state->Reg[DESTReg] = 0; 5923 state->Reg[DESTReg] = 0;
5757 } 5924 } else {
5758 else
5759 {
5760 state->Reg[DESTReg] = 1; 5925 state->Reg[DESTReg] = 1;
5761 } 5926 }
5762 5927
@@ -5795,12 +5960,9 @@ L_stm_s_takeabort:
5795 } 5960 }
5796 5961
5797 5962
5798 if (enter) 5963 if (enter) {
5799 {
5800 state->Reg[DESTReg] = 0; 5964 state->Reg[DESTReg] = 0;
5801 } 5965 } else {
5802 else
5803 {
5804 state->Reg[DESTReg] = 1; 5966 state->Reg[DESTReg] = 1;
5805 } 5967 }
5806 5968
@@ -5853,8 +6015,25 @@ L_stm_s_takeabort:
5853 6015
5854 case 0x01: 6016 case 0x01:
5855 case 0xf3: 6017 case 0xf3:
5856 printf ("Unhandled v6 insn: ssat\n"); 6018 //ichfly
5857 return 0; 6019 //SSAT16
6020 {
6021 u8 tar = BITS(12,15);
6022 u8 src = BITS(0, 3);
6023 u8 val = BITS(16, 19) + 1;
6024 s16 a1 = (state->Reg[src]);
6025 s16 a2 = (state->Reg[src] >> 0x10);
6026 s16 min = (s16)(0x8000) >> (16 - val);
6027 s16 max = 0x7FFF >> (16 - val);
6028 if (min > a1) a1 = min;
6029 if (max < a1) a1 = max;
6030 if (min > a2) a2 = min;
6031 if (max < a2) a2 = max;
6032 u32 temp2 = ((u32)(a2)) << 0x10;
6033 state->Reg[tar] = (a1&0xFFFF) | (temp2);
6034 }
6035
6036 return 1;
5858 default: 6037 default:
5859 break; 6038 break;
5860 } 6039 }
@@ -5944,8 +6123,21 @@ L_stm_s_takeabort:
5944 6123
5945 case 0x01: 6124 case 0x01:
5946 case 0xf3: 6125 case 0xf3:
5947 printf ("Unhandled v6 insn: usat\n"); 6126 //ichfly
5948 return 0; 6127 //USAT16
6128 {
6129 u8 tar = BITS(12, 15);
6130 u8 src = BITS(0, 3);
6131 u8 val = BITS(16, 19);
6132 s16 a1 = (state->Reg[src]);
6133 s16 a2 = (state->Reg[src] >> 0x10);
6134 s16 max = 0xFFFF >> (16 - val);
6135 if (max < a1) a1 = max;
6136 if (max < a2) a2 = max;
6137 u32 temp2 = ((u32)(a2)) << 0x10;
6138 state->Reg[tar] = (a1 & 0xFFFF) | (temp2);
6139 }
6140 return 1;
5949 default: 6141 default:
5950 break; 6142 break;
5951 } 6143 }
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index e4fa3c20a..454f60099 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -28,230 +28,270 @@
28#include "core/arm/skyeye_common/armdefs.h" 28#include "core/arm/skyeye_common/armdefs.h"
29#include "core/arm/skyeye_common/vfp/vfp.h" 29#include "core/arm/skyeye_common/vfp/vfp.h"
30 30
31#define DEBUG DBG
32
31//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ 33//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
32 34
33unsigned 35unsigned
34VFPInit (ARMul_State *state) 36VFPInit (ARMul_State *state)
35{ 37{
36 state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | 38 state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |
37 VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION; 39 VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION;
38 state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0; 40 state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0;
39 state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0; 41 state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0;
40 42
41 //persistent_state = state; 43 //persistent_state = state;
42 /* Reset only specify VFP_FPEXC_EN = '0' */ 44 /* Reset only specify VFP_FPEXC_EN = '0' */
43 45
44 return No_exp; 46 return 0;
45} 47}
46 48
47unsigned 49unsigned
48VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value) 50VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
49{ 51{
50 /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ 52 /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
51 int CoProc = BITS (8, 11); /* 10 or 11 */ 53 int CoProc = BITS (8, 11); /* 10 or 11 */
52 int OPC_1 = BITS (21, 23); 54 int OPC_1 = BITS (21, 23);
53 int Rt = BITS (12, 15); 55 int Rt = BITS (12, 15);
54 int CRn = BITS (16, 19); 56 int CRn = BITS (16, 19);
55 int CRm = BITS (0, 3); 57 int CRm = BITS (0, 3);
56 int OPC_2 = BITS (5, 7); 58 int OPC_2 = BITS (5, 7);
57 59
58 /* TODO check access permission */ 60 /* TODO check access permission */
59 61
60 /* CRn/opc1 CRm/opc2 */ 62 /* CRn/opc1 CRm/opc2 */
61 63
62 if (CoProc == 10 || CoProc == 11) 64 if (CoProc == 10 || CoProc == 11) {
63 { 65#define VFP_MRC_TRANS
64 #define VFP_MRC_TRANS 66#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
65 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 67#undef VFP_MRC_TRANS
66 #undef VFP_MRC_TRANS 68 }
67 } 69 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
68 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", 70 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
69 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); 71
70 72 return ARMul_CANT;
71 return ARMul_CANT;
72} 73}
73 74
74unsigned 75unsigned
75VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value) 76VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
76{ 77{
77 /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ 78 /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
78 int CoProc = BITS (8, 11); /* 10 or 11 */ 79 int CoProc = BITS (8, 11); /* 10 or 11 */
79 int OPC_1 = BITS (21, 23); 80 int OPC_1 = BITS (21, 23);
80 int Rt = BITS (12, 15); 81 int Rt = BITS (12, 15);
81 int CRn = BITS (16, 19); 82 int CRn = BITS (16, 19);
82 int CRm = BITS (0, 3); 83 int CRm = BITS (0, 3);
83 int OPC_2 = BITS (5, 7); 84 int OPC_2 = BITS (5, 7);
84 85
85 /* TODO check access permission */ 86 /* TODO check access permission */
86 87
87 /* CRn/opc1 CRm/opc2 */ 88 /* CRn/opc1 CRm/opc2 */
88 if (CoProc == 10 || CoProc == 11) 89 if (CoProc == 10 || CoProc == 11) {
89 { 90#define VFP_MCR_TRANS
90 #define VFP_MCR_TRANS 91#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
91 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 92#undef VFP_MCR_TRANS
92 #undef VFP_MCR_TRANS 93 }
93 } 94 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
94 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", 95 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
95 instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); 96
96 97 return ARMul_CANT;
97 return ARMul_CANT;
98} 98}
99 99
100unsigned 100unsigned
101VFPMRRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value1, ARMword * value2) 101VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * value2)
102{ 102{
103 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ 103 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
104 int CoProc = BITS (8, 11); /* 10 or 11 */ 104 int CoProc = BITS (8, 11); /* 10 or 11 */
105 int OPC_1 = BITS (4, 7); 105 int OPC_1 = BITS (4, 7);
106 int Rt = BITS (12, 15); 106 int Rt = BITS (12, 15);
107 int Rt2 = BITS (16, 19); 107 int Rt2 = BITS (16, 19);
108 int CRm = BITS (0, 3); 108 int CRm = BITS (0, 3);
109 109
110 if (CoProc == 10 || CoProc == 11) 110 if (CoProc == 10 || CoProc == 11) {
111 { 111#define VFP_MRRC_TRANS
112 #define VFP_MRRC_TRANS 112#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
113 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 113#undef VFP_MRRC_TRANS
114 #undef VFP_MRRC_TRANS 114 }
115 } 115 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
116 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", 116 instr, CoProc, OPC_1, Rt, Rt2, CRm);
117 instr, CoProc, OPC_1, Rt, Rt2, CRm); 117
118 118 return ARMul_CANT;
119 return ARMul_CANT;
120} 119}
121 120
122unsigned 121unsigned
123VFPMCRR (ARMul_State * state, unsigned type, ARMword instr, ARMword value1, ARMword value2) 122VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
124{ 123{
125 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ 124 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
126 int CoProc = BITS (8, 11); /* 10 or 11 */ 125 int CoProc = BITS (8, 11); /* 10 or 11 */
127 int OPC_1 = BITS (4, 7); 126 int OPC_1 = BITS (4, 7);
128 int Rt = BITS (12, 15); 127 int Rt = BITS (12, 15);
129 int Rt2 = BITS (16, 19); 128 int Rt2 = BITS (16, 19);
130 int CRm = BITS (0, 3); 129 int CRm = BITS (0, 3);
131 130
132 /* TODO check access permission */ 131 /* TODO check access permission */
133 132
134 /* CRn/opc1 CRm/opc2 */ 133 /* CRn/opc1 CRm/opc2 */
135 134
136 if (CoProc == 11 || CoProc == 10) 135 if (CoProc == 11 || CoProc == 10) {
137 { 136#define VFP_MCRR_TRANS
138 #define VFP_MCRR_TRANS 137#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
139 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 138#undef VFP_MCRR_TRANS
140 #undef VFP_MCRR_TRANS 139 }
141 } 140 DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
142 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", 141 instr, CoProc, OPC_1, Rt, Rt2, CRm);
143 instr, CoProc, OPC_1, Rt, Rt2, CRm); 142
144 143 return ARMul_CANT;
145 return ARMul_CANT;
146} 144}
147 145
148unsigned 146unsigned
149VFPSTC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value) 147VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
150{ 148{
151 /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ 149 /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
152 int CoProc = BITS (8, 11); /* 10 or 11 */ 150 int CoProc = BITS (8, 11); /* 10 or 11 */
153 int CRd = BITS (12, 15); 151 int CRd = BITS (12, 15);
154 int Rn = BITS (16, 19); 152 int Rn = BITS (16, 19);
155 int imm8 = BITS (0, 7); 153 int imm8 = BITS (0, 7);
156 int P = BIT(24); 154 int P = BIT(24);
157 int U = BIT(23); 155 int U = BIT(23);
158 int D = BIT(22); 156 int D = BIT(22);
159 int W = BIT(21); 157 int W = BIT(21);
160 158
161 /* TODO check access permission */ 159 /* TODO check access permission */
162 160
163 /* VSTM */ 161 /* VSTM */
164 if ( (P|U|D|W) == 0 ) 162 if ( (P|U|D|W) == 0 ) {
165 { 163 DEBUG("In %s, UNDEFINED\n", __FUNCTION__);
166 DEBUG_LOG(ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1); 164 exit(-1);
167 } 165 }
168 if (CoProc == 10 || CoProc == 11) 166 if (CoProc == 10 || CoProc == 11) {
169 { 167#if 1
170 #if 1 168 if (P == 0 && U == 0 && W == 0) {
171 if (P == 0 && U == 0 && W == 0) 169 DEBUG("VSTM Related encodings\n");
172 { 170 exit(-1);
173 DEBUG_LOG(ARM11, "VSTM Related encodings\n"); exit(-1); 171 }
174 } 172 if (P == U && W == 1) {
175 if (P == U && W == 1) 173 DEBUG("UNDEFINED\n");
176 { 174 exit(-1);
177 DEBUG_LOG(ARM11, "UNDEFINED\n"); exit(-1); 175 }
178 } 176#endif
179 #endif 177
180 178#define VFP_STC_TRANS
181 #define VFP_STC_TRANS 179#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
182 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 180#undef VFP_STC_TRANS
183 #undef VFP_STC_TRANS 181 }
184 } 182 DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
185 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", 183 instr, CoProc, CRd, Rn, imm8, P, U, D, W);
186 instr, CoProc, CRd, Rn, imm8, P, U, D, W); 184
187 185 return ARMul_CANT;
188 return ARMul_CANT;
189} 186}
190 187
191unsigned 188unsigned
192VFPLDC (ARMul_State * state, unsigned type, ARMword instr, ARMword value) 189VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
193{ 190{
194 /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ 191 /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
195 int CoProc = BITS (8, 11); /* 10 or 11 */ 192 int CoProc = BITS (8, 11); /* 10 or 11 */
196 int CRd = BITS (12, 15); 193 int CRd = BITS (12, 15);
197 int Rn = BITS (16, 19); 194 int Rn = BITS (16, 19);
198 int imm8 = BITS (0, 7); 195 int imm8 = BITS (0, 7);
199 int P = BIT(24); 196 int P = BIT(24);
200 int U = BIT(23); 197 int U = BIT(23);
201 int D = BIT(22); 198 int D = BIT(22);
202 int W = BIT(21); 199 int W = BIT(21);
203 200
204 /* TODO check access permission */ 201 /* TODO check access permission */
205 202
206 if ( (P|U|D|W) == 0 ) 203 if ( (P|U|D|W) == 0 ) {
207 { 204 DEBUG("In %s, UNDEFINED\n", __FUNCTION__);
208 DEBUG_LOG(ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1); 205 exit(-1);
209 } 206 }
210 if (CoProc == 10 || CoProc == 11) 207 if (CoProc == 10 || CoProc == 11) {
211 { 208#define VFP_LDC_TRANS
212 #define VFP_LDC_TRANS 209#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
213 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 210#undef VFP_LDC_TRANS
214 #undef VFP_LDC_TRANS 211 }
215 } 212 DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
216 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", 213 instr, CoProc, CRd, Rn, imm8, P, U, D, W);
217 instr, CoProc, CRd, Rn, imm8, P, U, D, W); 214
218 215 return ARMul_CANT;
219 return ARMul_CANT;
220} 216}
221 217
222unsigned 218unsigned
223VFPCDP (ARMul_State * state, unsigned type, ARMword instr) 219VFPCDP (ARMul_State * state, unsigned type, u32 instr)
224{ 220{
225 /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ 221 /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
226 int CoProc = BITS (8, 11); /* 10 or 11 */ 222 int CoProc = BITS (8, 11); /* 10 or 11 */
227 int OPC_1 = BITS (20, 23); 223 int OPC_1 = BITS (20, 23);
228 int CRd = BITS (12, 15); 224 int CRd = BITS (12, 15);
229 int CRn = BITS (16, 19); 225 int CRn = BITS (16, 19);
230 int CRm = BITS (0, 3); 226 int CRm = BITS (0, 3);
231 int OPC_2 = BITS (5, 7); 227 int OPC_2 = BITS (5, 7);
232 228
233 /* TODO check access permission */ 229 //ichfly
234 230 /*if ((instr & 0x0FBF0FD0) == 0x0EB70AC0) //vcvt.f64.f32 d8, s16 (s is bit 0-3 and LSB bit 22) (d is bit 12 - 15 MSB is Bit 6)
235 /* CRn/opc1 CRm/opc2 */ 231 {
236 232 struct vfp_double vdd;
237 if (CoProc == 10 || CoProc == 11) 233 struct vfp_single vsd;
238 { 234 int dn = BITS(12, 15) + (BIT(22) << 4);
239 #define VFP_CDP_TRANS 235 int sd = (BITS(0, 3) << 1) + BIT(5);
240 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" 236 s32 n = vfp_get_float(state, sd);
241 #undef VFP_CDP_TRANS 237 vfp_single_unpack(&vsd, n);
242 238 if (vsd.exponent & 0x80)
243 int exceptions = 0; 239 {
244 if (CoProc == 10) 240 vdd.exponent = (vsd.exponent&~0x80) | 0x400;
245 exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); 241 }
246 else 242 else
247 exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); 243 {
248 244 vdd.exponent = vsd.exponent | 0x380;
249 vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); 245 }
250 246 vdd.sign = vsd.sign;
251 return ARMul_DONE; 247 vdd.significand = (u64)(vsd.significand & ~0xC0000000) << 32; // I have no idea why but the 2 uppern bits are not from the significand
252 } 248 vfp_put_double(state, vfp_double_pack(&vdd), dn);
253 DEBUG_LOG(ARM11, "Can't identify %x\n", instr); 249 return ARMul_DONE;
254 return ARMul_CANT; 250 }
251 if ((instr & 0x0FBF0FD0) == 0x0EB70BC0) //vcvt.f32.f64 s15, d6
252 {
253 struct vfp_double vdd;
254 struct vfp_single vsd;
255 int sd = BITS(0, 3) + (BIT(5) << 4);
256 int dn = (BITS(12, 15) << 1) + BIT(22);
257 vfp_double_unpack(&vdd, vfp_get_double(state, sd));
258 if (vdd.exponent & 0x400) //todo if the exponent is to low or to high for this convert
259 {
260 vsd.exponent = (vdd.exponent) | 0x80;
261 }
262 else
263 {
264 vsd.exponent = vdd.exponent & ~0x80;
265 }
266 vsd.exponent &= 0xFF;
267 // vsd.exponent = vdd.exponent >> 3;
268 vsd.sign = vdd.sign;
269 vsd.significand = ((u64)(vdd.significand ) >> 32)& ~0xC0000000;
270 vfp_put_float(state, vfp_single_pack(&vsd), dn);
271 return ARMul_DONE;
272 }*/
273
274 /* TODO check access permission */
275
276 /* CRn/opc1 CRm/opc2 */
277
278 if (CoProc == 10 || CoProc == 11) {
279#define VFP_CDP_TRANS
280#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
281#undef VFP_CDP_TRANS
282
283 int exceptions = 0;
284 if (CoProc == 10)
285 exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
286 else
287 exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
288
289 vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
290
291 return ARMul_DONE;
292 }
293 DEBUG("Can't identify %x\n", instr);
294 return ARMul_CANT;
255} 295}
256 296
257 297
@@ -301,29 +341,29 @@ VFPCDP (ARMul_State * state, unsigned type, ARMword instr)
301/* Miscellaneous functions */ 341/* Miscellaneous functions */
302int32_t vfp_get_float(arm_core_t* state, unsigned int reg) 342int32_t vfp_get_float(arm_core_t* state, unsigned int reg)
303{ 343{
304 DBG("VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]); 344 DEBUG("VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]);
305 return state->ExtReg[reg]; 345 return state->ExtReg[reg];
306} 346}
307 347
308void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg) 348void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg)
309{ 349{
310 DBG("VFP put float: s%d <= [%08x]\n", reg, val); 350 DEBUG("VFP put float: s%d <= [%08x]\n", reg, val);
311 state->ExtReg[reg] = val; 351 state->ExtReg[reg] = val;
312} 352}
313 353
314uint64_t vfp_get_double(arm_core_t* state, unsigned int reg) 354uint64_t vfp_get_double(arm_core_t* state, unsigned int reg)
315{ 355{
316 uint64_t result; 356 uint64_t result;
317 result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2]; 357 result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2];
318 DBG("VFP get double: s[%d-%d]=[%016llx]\n", reg*2+1, reg*2, result); 358 DEBUG("VFP get double: s[%d-%d]=[%016llx]\n", reg*2+1, reg*2, result);
319 return result; 359 return result;
320} 360}
321 361
322void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg) 362void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg)
323{ 363{
324 DBG("VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg*2+1, reg*2, (uint32_t) (val>>32), (uint32_t) (val & 0xffffffff)); 364 DEBUG("VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg*2+1, reg*2, (uint32_t) (val>>32), (uint32_t) (val & 0xffffffff));
325 state->ExtReg[reg*2] = (uint32_t) (val & 0xffffffff); 365 state->ExtReg[reg*2] = (uint32_t) (val & 0xffffffff);
326 state->ExtReg[reg*2+1] = (uint32_t) (val>>32); 366 state->ExtReg[reg*2+1] = (uint32_t) (val>>32);
327} 367}
328 368
329 369
@@ -333,25 +373,25 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg)
333 */ 373 */
334void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr) 374void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr)
335{ 375{
336 int si_code = 0; 376 int si_code = 0;
337 377
338 vfpdebug("VFP: raising exceptions %08x\n", exceptions); 378 vfpdebug("VFP: raising exceptions %08x\n", exceptions);
339 379
340 if (exceptions == VFP_EXCEPTION_ERROR) { 380 if (exceptions == VFP_EXCEPTION_ERROR) {
341 DEBUG_LOG(ARM11, "unhandled bounce %x\n", inst); 381 DEBUG("unhandled bounce %x\n", inst);
342 exit(-1); 382 exit(-1);
343 return; 383 return;
344 } 384 }
345 385
346 /* 386 /*
347 * If any of the status flags are set, update the FPSCR. 387 * If any of the status flags are set, update the FPSCR.
348 * Comparison instructions always return at least one of 388 * Comparison instructions always return at least one of
349 * these flags set. 389 * these flags set.
350 */ 390 */
351 if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) 391 if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
352 fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); 392 fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V);
353 393
354 fpscr |= exceptions; 394 fpscr |= exceptions;
355 395
356 state->VFP[VFP_OFFSET(VFP_FPSCR)] = fpscr; 396 state->VFP[VFP_OFFSET(VFP_FPSCR)] = fpscr;
357} 397}
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h
index 5076e59f7..f0896fc87 100644
--- a/src/core/arm/skyeye_common/vfp/vfp_helper.h
+++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h
@@ -44,7 +44,7 @@
44#define pr_info //printf 44#define pr_info //printf
45#define pr_debug //printf 45#define pr_debug //printf
46 46
47static u32 vfp_fls(int x); 47static u32 fls(int x);
48#define do_div(n, base) {n/=base;} 48#define do_div(n, base) {n/=base;}
49 49
50/* From vfpinstr.h */ 50/* From vfpinstr.h */
@@ -502,7 +502,7 @@ struct op {
502 u32 flags; 502 u32 flags;
503}; 503};
504 504
505static u32 vfp_fls(int x) 505static u32 fls(int x)
506{ 506{
507 int r = 32; 507 int r = 32;
508 508
@@ -532,4 +532,9 @@ static u32 vfp_fls(int x)
532 532
533} 533}
534 534
535u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func);
536u32 vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr);
537u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr);
538u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* dm, u32 fpscr);
539
535#endif 540#endif
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
index 13411ad80..765c1f6bc 100644
--- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
@@ -56,163 +56,291 @@
56#include "core/arm/skyeye_common/vfp/asm_vfp.h" 56#include "core/arm/skyeye_common/vfp/asm_vfp.h"
57 57
58static struct vfp_double vfp_double_default_qnan = { 58static struct vfp_double vfp_double_default_qnan = {
59 //.exponent = 2047, 59 2047,
60 //.sign = 0, 60 0,
61 //.significand = VFP_DOUBLE_SIGNIFICAND_QNAN, 61 VFP_DOUBLE_SIGNIFICAND_QNAN,
62}; 62};
63 63
64static void vfp_double_dump(const char *str, struct vfp_double *d) 64static void vfp_double_dump(const char *str, struct vfp_double *d)
65{ 65{
66 pr_debug("VFP: %s: sign=%d exponent=%d significand=%016llx\n", 66 pr_debug("VFP: %s: sign=%d exponent=%d significand=%016llx\n",
67 str, d->sign != 0, d->exponent, d->significand); 67 str, d->sign != 0, d->exponent, d->significand);
68} 68}
69 69
70static void vfp_double_normalise_denormal(struct vfp_double *vd) 70static void vfp_double_normalise_denormal(struct vfp_double *vd)
71{ 71{
72 int bits = 31 - vfp_fls(vd->significand >> 32); 72 int bits = 31 - fls((ARMword)(vd->significand >> 32));
73 if (bits == 31) 73 if (bits == 31)
74 bits = 63 - vfp_fls(vd->significand); 74 bits = 63 - fls((ARMword)vd->significand);
75 75
76 vfp_double_dump("normalise_denormal: in", vd); 76 vfp_double_dump("normalise_denormal: in", vd);
77 77
78 if (bits) { 78 if (bits) {
79 vd->exponent -= bits - 1; 79 vd->exponent -= bits - 1;
80 vd->significand <<= bits; 80 vd->significand <<= bits;
81 } 81 }
82 82
83 vfp_double_dump("normalise_denormal: out", vd); 83 vfp_double_dump("normalise_denormal: out", vd);
84} 84}
85 85
86u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) 86u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func)
87{ 87{
88 u64 significand, incr; 88 u64 significand, incr;
89 int exponent, shift, underflow; 89 int exponent, shift, underflow;
90 u32 rmode; 90 u32 rmode;
91 91
92 vfp_double_dump("pack: in", vd); 92 vfp_double_dump("pack: in", vd);
93 93
94 /* 94 /*
95 * Infinities and NaNs are a special case. 95 * Infinities and NaNs are a special case.
96 */ 96 */
97 if (vd->exponent == 2047 && (vd->significand == 0 || exceptions)) 97 if (vd->exponent == 2047 && (vd->significand == 0 || exceptions))
98 goto pack; 98 goto pack;
99 99
100 /* 100 /*
101 * Special-case zero. 101 * Special-case zero.
102 */ 102 */
103 if (vd->significand == 0) { 103 if (vd->significand == 0) {
104 vd->exponent = 0; 104 vd->exponent = 0;
105 goto pack; 105 goto pack;
106 } 106 }
107 107
108 exponent = vd->exponent; 108 exponent = vd->exponent;
109 significand = vd->significand; 109 significand = vd->significand;
110 110
111 shift = 32 - vfp_fls(significand >> 32); 111 shift = 32 - fls((ARMword)(significand >> 32));
112 if (shift == 32) 112 if (shift == 32)
113 shift = 64 - vfp_fls(significand); 113 shift = 64 - fls((ARMword)significand);
114 if (shift) { 114 if (shift) {
115 exponent -= shift; 115 exponent -= shift;
116 significand <<= shift; 116 significand <<= shift;
117 } 117 }
118 118
119#if 1 119#if 1
120 vd->exponent = exponent; 120 vd->exponent = exponent;
121 vd->significand = significand; 121 vd->significand = significand;
122 vfp_double_dump("pack: normalised", vd); 122 vfp_double_dump("pack: normalised", vd);
123#endif 123#endif
124 124
125 /* 125 /*
126 * Tiny number? 126 * Tiny number?
127 */ 127 */
128 underflow = exponent < 0; 128 underflow = exponent < 0;
129 if (underflow) { 129 if (underflow) {
130 significand = vfp_shiftright64jamming(significand, -exponent); 130 significand = vfp_shiftright64jamming(significand, -exponent);
131 exponent = 0; 131 exponent = 0;
132#if 1 132#if 1
133 vd->exponent = exponent; 133 vd->exponent = exponent;
134 vd->significand = significand; 134 vd->significand = significand;
135 vfp_double_dump("pack: tiny number", vd); 135 vfp_double_dump("pack: tiny number", vd);
136#endif 136#endif
137 if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1))) 137 if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1)))
138 underflow = 0; 138 underflow = 0;
139 } 139 }
140 140
141 /* 141 /*
142 * Select rounding increment. 142 * Select rounding increment.
143 */ 143 */
144 incr = 0; 144 incr = 0;
145 rmode = fpscr & FPSCR_RMODE_MASK; 145 rmode = fpscr & FPSCR_RMODE_MASK;
146 146
147 if (rmode == FPSCR_ROUND_NEAREST) { 147 if (rmode == FPSCR_ROUND_NEAREST) {
148 incr = 1ULL << VFP_DOUBLE_LOW_BITS; 148 incr = 1ULL << VFP_DOUBLE_LOW_BITS;
149 if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0) 149 if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0)
150 incr -= 1; 150 incr -= 1;
151 } else if (rmode == FPSCR_ROUND_TOZERO) { 151 }
152 incr = 0; 152 else if (rmode == FPSCR_ROUND_TOZERO) {
153 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0)) 153 incr = 0;
154 incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1; 154 }
155 155 else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0))
156 pr_debug("VFP: rounding increment = 0x%08llx\n", incr); 156 incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1;
157 157
158 /* 158 pr_debug("VFP: rounding increment = 0x%08llx\n", incr);
159 * Is our rounding going to overflow? 159
160 */ 160 /*
161 if ((significand + incr) < significand) { 161 * Is our rounding going to overflow?
162 exponent += 1; 162 */
163 significand = (significand >> 1) | (significand & 1); 163 if ((significand + incr) < significand) {
164 incr >>= 1; 164 exponent += 1;
165 significand = (significand >> 1) | (significand & 1);
166 incr >>= 1;
165#if 1 167#if 1
166 vd->exponent = exponent; 168 vd->exponent = exponent;
167 vd->significand = significand; 169 vd->significand = significand;
168 vfp_double_dump("pack: overflow", vd); 170 vfp_double_dump("pack: overflow", vd);
169#endif 171#endif
170 } 172 }
171 173
172 /* 174 /*
173 * If any of the low bits (which will be shifted out of the 175 * If any of the low bits (which will be shifted out of the
174 * number) are non-zero, the result is inexact. 176 * number) are non-zero, the result is inexact.
175 */ 177 */
176 if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1)) 178 if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1))
177 exceptions |= FPSCR_IXC; 179 exceptions |= FPSCR_IXC;
178 180
179 /* 181 /*
180 * Do our rounding. 182 * Do our rounding.
181 */ 183 */
182 significand += incr; 184 significand += incr;
183 185
184 /* 186 /*
185 * Infinity? 187 * Infinity?
186 */ 188 */
187 if (exponent >= 2046) { 189 if (exponent >= 2046) {
188 exceptions |= FPSCR_OFC | FPSCR_IXC; 190 exceptions |= FPSCR_OFC | FPSCR_IXC;
189 if (incr == 0) { 191 if (incr == 0) {
190 vd->exponent = 2045; 192 vd->exponent = 2045;
191 vd->significand = 0x7fffffffffffffffULL; 193 vd->significand = 0x7fffffffffffffffULL;
192 } else { 194 }
193 vd->exponent = 2047; /* infinity */ 195 else {
194 vd->significand = 0; 196 vd->exponent = 2047; /* infinity */
195 } 197 vd->significand = 0;
196 } else { 198 }
197 if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0) 199 }
198 exponent = 0; 200 else {
199 if (exponent || significand > 0x8000000000000000ULL) 201 if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0)
200 underflow = 0; 202 exponent = 0;
201 if (underflow) 203 if (exponent || significand > 0x8000000000000000ULL)
202 exceptions |= FPSCR_UFC; 204 underflow = 0;
203 vd->exponent = exponent; 205 if (underflow)
204 vd->significand = significand >> 1; 206 exceptions |= FPSCR_UFC;
205 } 207 vd->exponent = exponent;
206 208 vd->significand = significand >> 1;
209 }
207 pack: 210 pack:
208 vfp_double_dump("pack: final", vd); 211 return 0;
209 { 212}
210 s64 d = vfp_double_pack(vd); 213
211 pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, 214u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func)
212 dd, d, exceptions); 215{
213 vfp_put_double(state, d, dd); 216 u64 significand, incr;
214 } 217 int exponent, shift, underflow;
215 return exceptions; 218 u32 rmode;
219
220 vfp_double_dump("pack: in", vd);
221
222 /*
223 * Infinities and NaNs are a special case.
224 */
225 if (vd->exponent == 2047 && (vd->significand == 0 || exceptions))
226 goto pack;
227
228 /*
229 * Special-case zero.
230 */
231 if (vd->significand == 0) {
232 vd->exponent = 0;
233 goto pack;
234 }
235
236 exponent = vd->exponent;
237 significand = vd->significand;
238
239 shift = 32 - fls((ARMword)(significand >> 32));
240 if (shift == 32)
241 shift = 64 - fls((ARMword)significand);
242 if (shift) {
243 exponent -= shift;
244 significand <<= shift;
245 }
246
247#if 1
248 vd->exponent = exponent;
249 vd->significand = significand;
250 vfp_double_dump("pack: normalised", vd);
251#endif
252
253 /*
254 * Tiny number?
255 */
256 underflow = exponent < 0;
257 if (underflow) {
258 significand = vfp_shiftright64jamming(significand, -exponent);
259 exponent = 0;
260#if 1
261 vd->exponent = exponent;
262 vd->significand = significand;
263 vfp_double_dump("pack: tiny number", vd);
264#endif
265 if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1)))
266 underflow = 0;
267 }
268
269 /*
270 * Select rounding increment.
271 */
272 incr = 0;
273 rmode = fpscr & FPSCR_RMODE_MASK;
274
275 if (rmode == FPSCR_ROUND_NEAREST) {
276 incr = 1ULL << VFP_DOUBLE_LOW_BITS;
277 if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0)
278 incr -= 1;
279 } else if (rmode == FPSCR_ROUND_TOZERO) {
280 incr = 0;
281 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0))
282 incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1;
283
284 pr_debug("VFP: rounding increment = 0x%08llx\n", incr);
285
286 /*
287 * Is our rounding going to overflow?
288 */
289 if ((significand + incr) < significand) {
290 exponent += 1;
291 significand = (significand >> 1) | (significand & 1);
292 incr >>= 1;
293#if 1
294 vd->exponent = exponent;
295 vd->significand = significand;
296 vfp_double_dump("pack: overflow", vd);
297#endif
298 }
299
300 /*
301 * If any of the low bits (which will be shifted out of the
302 * number) are non-zero, the result is inexact.
303 */
304 if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1))
305 exceptions |= FPSCR_IXC;
306
307 /*
308 * Do our rounding.
309 */
310 significand += incr;
311
312 /*
313 * Infinity?
314 */
315 if (exponent >= 2046) {
316 exceptions |= FPSCR_OFC | FPSCR_IXC;
317 if (incr == 0) {
318 vd->exponent = 2045;
319 vd->significand = 0x7fffffffffffffffULL;
320 } else {
321 vd->exponent = 2047; /* infinity */
322 vd->significand = 0;
323 }
324 } else {
325 if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0)
326 exponent = 0;
327 if (exponent || significand > 0x8000000000000000ULL)
328 underflow = 0;
329 if (underflow)
330 exceptions |= FPSCR_UFC;
331 vd->exponent = exponent;
332 vd->significand = significand >> 1;
333 }
334
335pack:
336 vfp_double_dump("pack: final", vd);
337 {
338 s64 d = vfp_double_pack(vd);
339 pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func,
340 dd, d, exceptions);
341 vfp_put_double(state, d, dd);
342 }
343 return exceptions;
216} 344}
217 345
218/* 346/*
@@ -221,43 +349,43 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd,
221 */ 349 */
222static u32 350static u32
223vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, 351vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn,
224 struct vfp_double *vdm, u32 fpscr) 352 struct vfp_double *vdm, u32 fpscr)
225{ 353{
226 struct vfp_double *nan; 354 struct vfp_double *nan;
227 int tn, tm = 0; 355 int tn, tm = 0;
228 356
229 tn = vfp_double_type(vdn); 357 tn = vfp_double_type(vdn);
230 358
231 if (vdm) 359 if (vdm)
232 tm = vfp_double_type(vdm); 360 tm = vfp_double_type(vdm);
233 361
234 if (fpscr & FPSCR_DEFAULT_NAN) 362 if (fpscr & FPSCR_DEFAULT_NAN)
235 /* 363 /*
236 * Default NaN mode - always returns a quiet NaN 364 * Default NaN mode - always returns a quiet NaN
237 */ 365 */
238 nan = &vfp_double_default_qnan; 366 nan = &vfp_double_default_qnan;
239 else { 367 else {
240 /* 368 /*
241 * Contemporary mode - select the first signalling 369 * Contemporary mode - select the first signalling
242 * NAN, or if neither are signalling, the first 370 * NAN, or if neither are signalling, the first
243 * quiet NAN. 371 * quiet NAN.
244 */ 372 */
245 if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN)) 373 if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN))
246 nan = vdn; 374 nan = vdn;
247 else 375 else
248 nan = vdm; 376 nan = vdm;
249 /* 377 /*
250 * Make the NaN quiet. 378 * Make the NaN quiet.
251 */ 379 */
252 nan->significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; 380 nan->significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
253 } 381 }
254 382
255 *vdd = *nan; 383 *vdd = *nan;
256 384
257 /* 385 /*
258 * If one was a signalling NAN, raise invalid operation. 386 * If one was a signalling NAN, raise invalid operation.
259 */ 387 */
260 return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG; 388 return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG;
261} 389}
262 390
263/* 391/*
@@ -265,108 +393,108 @@ vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn,
265 */ 393 */
266static u32 vfp_double_fabs(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 394static u32 vfp_double_fabs(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
267{ 395{
268 pr_debug("In %s\n", __FUNCTION__); 396 pr_debug("In %s\n", __FUNCTION__);
269 vfp_put_double(state, vfp_double_packed_abs(vfp_get_double(state, dm)), dd); 397 vfp_put_double(state, vfp_double_packed_abs(vfp_get_double(state, dm)), dd);
270 return 0; 398 return 0;
271} 399}
272 400
273static u32 vfp_double_fcpy(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 401static u32 vfp_double_fcpy(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
274{ 402{
275 pr_debug("In %s\n", __FUNCTION__); 403 pr_debug("In %s\n", __FUNCTION__);
276 vfp_put_double(state, vfp_get_double(state, dm), dd); 404 vfp_put_double(state, vfp_get_double(state, dm), dd);
277 return 0; 405 return 0;
278} 406}
279 407
280static u32 vfp_double_fneg(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 408static u32 vfp_double_fneg(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
281{ 409{
282 pr_debug("In %s\n", __FUNCTION__); 410 pr_debug("In %s\n", __FUNCTION__);
283 vfp_put_double(state, vfp_double_packed_negate(vfp_get_double(state, dm)), dd); 411 vfp_put_double(state, vfp_double_packed_negate(vfp_get_double(state, dm)), dd);
284 return 0; 412 return 0;
285} 413}
286 414
287static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 415static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
288{ 416{
289 pr_debug("In %s\n", __FUNCTION__); 417 pr_debug("In %s\n", __FUNCTION__);
290 struct vfp_double vdm, vdd, *vdp; 418 vfp_double vdm, vdd, *vdp;
291 int ret, tm; 419 int ret, tm;
292 420
293 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 421 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
294 tm = vfp_double_type(&vdm); 422 tm = vfp_double_type(&vdm);
295 if (tm & (VFP_NAN|VFP_INFINITY)) { 423 if (tm & (VFP_NAN|VFP_INFINITY)) {
296 vdp = &vdd; 424 vdp = &vdd;
297 425
298 if (tm & VFP_NAN) 426 if (tm & VFP_NAN)
299 ret = vfp_propagate_nan(vdp, &vdm, NULL, fpscr); 427 ret = vfp_propagate_nan(vdp, &vdm, NULL, fpscr);
300 else if (vdm.sign == 0) { 428 else if (vdm.sign == 0) {
301 sqrt_copy: 429sqrt_copy:
302 vdp = &vdm; 430 vdp = &vdm;
303 ret = 0; 431 ret = 0;
304 } else { 432 } else {
305 sqrt_invalid: 433sqrt_invalid:
306 vdp = &vfp_double_default_qnan; 434 vdp = &vfp_double_default_qnan;
307 ret = FPSCR_IOC; 435 ret = FPSCR_IOC;
308 } 436 }
309 vfp_put_double(state, vfp_double_pack(vdp), dd); 437 vfp_put_double(state, vfp_double_pack(vdp), dd);
310 return ret; 438 return ret;
311 } 439 }
312 440
313 /* 441 /*
314 * sqrt(+/- 0) == +/- 0 442 * sqrt(+/- 0) == +/- 0
315 */ 443 */
316 if (tm & VFP_ZERO) 444 if (tm & VFP_ZERO)
317 goto sqrt_copy; 445 goto sqrt_copy;
318 446
319 /* 447 /*
320 * Normalise a denormalised number 448 * Normalise a denormalised number
321 */ 449 */
322 if (tm & VFP_DENORMAL) 450 if (tm & VFP_DENORMAL)
323 vfp_double_normalise_denormal(&vdm); 451 vfp_double_normalise_denormal(&vdm);
324 452
325 /* 453 /*
326 * sqrt(<0) = invalid 454 * sqrt(<0) = invalid
327 */ 455 */
328 if (vdm.sign) 456 if (vdm.sign)
329 goto sqrt_invalid; 457 goto sqrt_invalid;
330 458
331 vfp_double_dump("sqrt", &vdm); 459 vfp_double_dump("sqrt", &vdm);
332 460
333 /* 461 /*
334 * Estimate the square root. 462 * Estimate the square root.
335 */ 463 */
336 vdd.sign = 0; 464 vdd.sign = 0;
337 vdd.exponent = ((vdm.exponent - 1023) >> 1) + 1023; 465 vdd.exponent = ((vdm.exponent - 1023) >> 1) + 1023;
338 vdd.significand = (u64)vfp_estimate_sqrt_significand(vdm.exponent, vdm.significand >> 32) << 31; 466 vdd.significand = (u64)vfp_estimate_sqrt_significand(vdm.exponent, vdm.significand >> 32) << 31;
339 467
340 vfp_double_dump("sqrt estimate1", &vdd); 468 vfp_double_dump("sqrt estimate1", &vdd);
341 469
342 vdm.significand >>= 1 + (vdm.exponent & 1); 470 vdm.significand >>= 1 + (vdm.exponent & 1);
343 vdd.significand += 2 + vfp_estimate_div128to64(vdm.significand, 0, vdd.significand); 471 vdd.significand += 2 + vfp_estimate_div128to64(vdm.significand, 0, vdd.significand);
344 472
345 vfp_double_dump("sqrt estimate2", &vdd); 473 vfp_double_dump("sqrt estimate2", &vdd);
346 474
347 /* 475 /*
348 * And now adjust. 476 * And now adjust.
349 */ 477 */
350 if ((vdd.significand & VFP_DOUBLE_LOW_BITS_MASK) <= 5) { 478 if ((vdd.significand & VFP_DOUBLE_LOW_BITS_MASK) <= 5) {
351 if (vdd.significand < 2) { 479 if (vdd.significand < 2) {
352 vdd.significand = ~0ULL; 480 vdd.significand = ~0ULL;
353 } else { 481 } else {
354 u64 termh, terml, remh, reml; 482 u64 termh, terml, remh, reml;
355 vdm.significand <<= 2; 483 vdm.significand <<= 2;
356 mul64to128(&termh, &terml, vdd.significand, vdd.significand); 484 mul64to128(&termh, &terml, vdd.significand, vdd.significand);
357 sub128(&remh, &reml, vdm.significand, 0, termh, terml); 485 sub128(&remh, &reml, vdm.significand, 0, termh, terml);
358 while ((s64)remh < 0) { 486 while ((s64)remh < 0) {
359 vdd.significand -= 1; 487 vdd.significand -= 1;
360 shift64left(&termh, &terml, vdd.significand); 488 shift64left(&termh, &terml, vdd.significand);
361 terml |= 1; 489 terml |= 1;
362 add128(&remh, &reml, remh, reml, termh, terml); 490 add128(&remh, &reml, remh, reml, termh, terml);
363 } 491 }
364 vdd.significand |= (remh | reml) != 0; 492 vdd.significand |= (remh | reml) != 0;
365 } 493 }
366 } 494 }
367 vdd.significand = vfp_shiftright64jamming(vdd.significand, 1); 495 vdd.significand = vfp_shiftright64jamming(vdd.significand, 1);
368 496
369 return vfp_double_normaliseround(state, dd, &vdd, fpscr, 0, "fsqrt"); 497 return vfp_double_normaliseround(state, dd, &vdd, fpscr, 0, "fsqrt");
370} 498}
371 499
372/* 500/*
@@ -377,319 +505,362 @@ static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32
377 */ 505 */
378static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u32 fpscr) 506static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u32 fpscr)
379{ 507{
380 s64 d, m; 508 s64 d, m;
381 u32 ret = 0; 509 u32 ret = 0;
382 510
383 pr_debug("In %s, state=0x%x, fpscr=0x%x\n", __FUNCTION__, state, fpscr); 511 pr_debug("In %s, state=0x%x, fpscr=0x%x\n", __FUNCTION__, state, fpscr);
384 m = vfp_get_double(state, dm); 512 m = vfp_get_double(state, dm);
385 if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { 513 if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) {
386 ret |= FPSCR_C | FPSCR_V; 514 ret |= FPSCR_C | FPSCR_V;
387 if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) 515 if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1))))
388 /* 516 /*
389 * Signalling NaN, or signalling on quiet NaN 517 * Signalling NaN, or signalling on quiet NaN
390 */ 518 */
391 ret |= FPSCR_IOC; 519 ret |= FPSCR_IOC;
392 } 520 }
393 521
394 d = vfp_get_double(state, dd); 522 d = vfp_get_double(state, dd);
395 if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) { 523 if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) {
396 ret |= FPSCR_C | FPSCR_V; 524 ret |= FPSCR_C | FPSCR_V;
397 if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) 525 if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1))))
398 /* 526 /*
399 * Signalling NaN, or signalling on quiet NaN 527 * Signalling NaN, or signalling on quiet NaN
400 */ 528 */
401 ret |= FPSCR_IOC; 529 ret |= FPSCR_IOC;
402 } 530 }
403 531
404 if (ret == 0) { 532 if (ret == 0) {
405 //printf("In %s, d=%lld, m =%lld\n ", __FUNCTION__, d, m); 533 //printf("In %s, d=%lld, m =%lld\n ", __FUNCTION__, d, m);
406 if (d == m || vfp_double_packed_abs(d | m) == 0) { 534 if (d == m || vfp_double_packed_abs(d | m) == 0) {
407 /* 535 /*
408 * equal 536 * equal
409 */ 537 */
410 ret |= FPSCR_Z | FPSCR_C; 538 ret |= FPSCR_Z | FPSCR_C;
411 //printf("In %s,1 ret=0x%x\n", __FUNCTION__, ret); 539 //printf("In %s,1 ret=0x%x\n", __FUNCTION__, ret);
412 } else if (vfp_double_packed_sign(d ^ m)) { 540 } else if (vfp_double_packed_sign(d ^ m)) {
413 /* 541 /*
414 * different signs 542 * different signs
415 */ 543 */
416 if (vfp_double_packed_sign(d)) 544 if (vfp_double_packed_sign(d))
417 /* 545 /*
418 * d is negative, so d < m 546 * d is negative, so d < m
419 */ 547 */
420 ret |= FPSCR_N; 548 ret |= FPSCR_N;
421 else 549 else
422 /* 550 /*
423 * d is positive, so d > m 551 * d is positive, so d > m
424 */ 552 */
425 ret |= FPSCR_C; 553 ret |= FPSCR_C;
426 } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) { 554 } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) {
427 /* 555 /*
428 * d < m 556 * d < m
429 */ 557 */
430 ret |= FPSCR_N; 558 ret |= FPSCR_N;
431 } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) { 559 } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) {
432 /* 560 /*
433 * d > m 561 * d > m
434 */ 562 */
435 ret |= FPSCR_C; 563 ret |= FPSCR_C;
436 } 564 }
437 } 565 }
438 pr_debug("In %s, state=0x%x, ret=0x%x\n", __FUNCTION__, state, ret); 566 pr_debug("In %s, state=0x%x, ret=0x%x\n", __FUNCTION__, state, ret);
439 567
440 return ret; 568 return ret;
441} 569}
442 570
443static u32 vfp_double_fcmp(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 571static u32 vfp_double_fcmp(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
444{ 572{
445 pr_debug("In %s\n", __FUNCTION__); 573 pr_debug("In %s\n", __FUNCTION__);
446 return vfp_compare(state, dd, 0, dm, fpscr); 574 return vfp_compare(state, dd, 0, dm, fpscr);
447} 575}
448 576
449static u32 vfp_double_fcmpe(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 577static u32 vfp_double_fcmpe(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
450{ 578{
451 pr_debug("In %s\n", __FUNCTION__); 579 pr_debug("In %s\n", __FUNCTION__);
452 return vfp_compare(state, dd, 1, dm, fpscr); 580 return vfp_compare(state, dd, 1, dm, fpscr);
453} 581}
454 582
455static u32 vfp_double_fcmpz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 583static u32 vfp_double_fcmpz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
456{ 584{
457 pr_debug("In %s\n", __FUNCTION__); 585 pr_debug("In %s\n", __FUNCTION__);
458 return vfp_compare(state, dd, 0, VFP_REG_ZERO, fpscr); 586 return vfp_compare(state, dd, 0, VFP_REG_ZERO, fpscr);
459} 587}
460 588
461static u32 vfp_double_fcmpez(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 589static u32 vfp_double_fcmpez(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
462{ 590{
463 pr_debug("In %s\n", __FUNCTION__); 591 pr_debug("In %s\n", __FUNCTION__);
464 return vfp_compare(state, dd, 1, VFP_REG_ZERO, fpscr); 592 return vfp_compare(state, dd, 1, VFP_REG_ZERO, fpscr);
593}
594
595u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* dm, u32 fpscr) //ichfly for internal use only
596{
597 struct vfp_single vsd;
598 int tm;
599 u32 exceptions = 0;
600
601 pr_debug("In %s\n", __FUNCTION__);
602
603 tm = vfp_double_type(dm);
604
605 /*
606 * If we have a signalling NaN, signal invalid operation.
607 */
608 if (tm == VFP_SNAN)
609 exceptions = FPSCR_IOC;
610
611 if (tm & VFP_DENORMAL)
612 vfp_double_normalise_denormal(dm);
613
614 vsd.sign = dm->sign;
615 vsd.significand = vfp_hi64to32jamming(dm->significand);
616
617 /*
618 * If we have an infinity or a NaN, the exponent must be 255
619 */
620 if (tm & (VFP_INFINITY | VFP_NAN)) {
621 vsd.exponent = 255;
622 if (tm == VFP_QNAN)
623 vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
624 goto pack_nan;
625 }
626 else if (tm & VFP_ZERO)
627 vsd.exponent = 0;
628 else
629 vsd.exponent = dm->exponent - (1023 - 127);
630
631 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fcvts");
632
633pack_nan:
634 vfp_put_float(state, vfp_single_pack(&vsd), sd);
635 return exceptions;
465} 636}
466 637
467static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) 638static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr)
468{ 639{
469 struct vfp_double vdm; 640 struct vfp_double vdm;
470 struct vfp_single vsd; 641 struct vfp_single vsd;
471 int tm; 642 int tm;
472 u32 exceptions = 0; 643 u32 exceptions = 0;
473 644
474 pr_debug("In %s\n", __FUNCTION__); 645 pr_debug("In %s\n", __FUNCTION__);
475 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 646 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
476 647
477 tm = vfp_double_type(&vdm); 648 tm = vfp_double_type(&vdm);
478 649
479 /* 650 /*
480 * If we have a signalling NaN, signal invalid operation. 651 * If we have a signalling NaN, signal invalid operation.
481 */ 652 */
482 if (tm == VFP_SNAN) 653 if (tm == VFP_SNAN)
483 exceptions = FPSCR_IOC; 654 exceptions = FPSCR_IOC;
484 655
485 if (tm & VFP_DENORMAL) 656 if (tm & VFP_DENORMAL)
486 vfp_double_normalise_denormal(&vdm); 657 vfp_double_normalise_denormal(&vdm);
487 658
488 vsd.sign = vdm.sign; 659 vsd.sign = vdm.sign;
489 vsd.significand = vfp_hi64to32jamming(vdm.significand); 660 vsd.significand = vfp_hi64to32jamming(vdm.significand);
490 661
491 /* 662 /*
492 * If we have an infinity or a NaN, the exponent must be 255 663 * If we have an infinity or a NaN, the exponent must be 255
493 */ 664 */
494 if (tm & (VFP_INFINITY|VFP_NAN)) { 665 if (tm & (VFP_INFINITY|VFP_NAN)) {
495 vsd.exponent = 255; 666 vsd.exponent = 255;
496 if (tm == VFP_QNAN) 667 if (tm == VFP_QNAN)
497 vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; 668 vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
498 goto pack_nan; 669 goto pack_nan;
499 } else if (tm & VFP_ZERO) 670 } else if (tm & VFP_ZERO)
500 vsd.exponent = 0; 671 vsd.exponent = 0;
501 else 672 else
502 vsd.exponent = vdm.exponent - (1023 - 127); 673 vsd.exponent = vdm.exponent - (1023 - 127);
503 674
504 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fcvts"); 675 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fcvts");
505 676
506 pack_nan: 677pack_nan:
507 vfp_put_float(state, vfp_single_pack(&vsd), sd); 678 vfp_put_float(state, vfp_single_pack(&vsd), sd);
508 return exceptions; 679 return exceptions;
509} 680}
510 681
511static u32 vfp_double_fuito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 682static u32 vfp_double_fuito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
512{ 683{
513 struct vfp_double vdm; 684 struct vfp_double vdm;
514 u32 m = vfp_get_float(state, dm); 685 u32 m = vfp_get_float(state, dm);
515 686
516 pr_debug("In %s\n", __FUNCTION__); 687 pr_debug("In %s\n", __FUNCTION__);
517 vdm.sign = 0; 688 vdm.sign = 0;
518 vdm.exponent = 1023 + 63 - 1; 689 vdm.exponent = 1023 + 63 - 1;
519 vdm.significand = (u64)m; 690 vdm.significand = (u64)m;
520 691
521 return vfp_double_normaliseround(state, dd, &vdm, fpscr, 0, "fuito"); 692 return vfp_double_normaliseround(state, dd, &vdm, fpscr, 0, "fuito");
522} 693}
523 694
524static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 695static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
525{ 696{
526 struct vfp_double vdm; 697 struct vfp_double vdm;
527 u32 m = vfp_get_float(state, dm); 698 u32 m = vfp_get_float(state, dm);
528 699
529 pr_debug("In %s\n", __FUNCTION__); 700 pr_debug("In %s\n", __FUNCTION__);
530 vdm.sign = (m & 0x80000000) >> 16; 701 vdm.sign = (m & 0x80000000) >> 16;
531 vdm.exponent = 1023 + 63 - 1; 702 vdm.exponent = 1023 + 63 - 1;
532 vdm.significand = vdm.sign ? -m : m; 703 vdm.significand = vdm.sign ? -m : m;
533 704
534 return vfp_double_normaliseround(state, dd, &vdm, fpscr, 0, "fsito"); 705 return vfp_double_normaliseround(state, dd, &vdm, fpscr, 0, "fsito");
535} 706}
536 707
537static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) 708static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 fpscr)
538{ 709{
539 struct vfp_double vdm; 710 struct vfp_double vdm;
540 u32 d, exceptions = 0; 711 u32 d, exceptions = 0;
541 int rmode = fpscr & FPSCR_RMODE_MASK; 712 int rmode = fpscr & FPSCR_RMODE_MASK;
542 int tm; 713 int tm;
543 714
544 pr_debug("In %s\n", __FUNCTION__); 715 pr_debug("In %s\n", __FUNCTION__);
545 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 716 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
546 717
547 /* 718 /*
548 * Do we have a denormalised number? 719 * Do we have a denormalised number?
549 */ 720 */
550 tm = vfp_double_type(&vdm); 721 tm = vfp_double_type(&vdm);
551 if (tm & VFP_DENORMAL) 722 if (tm & VFP_DENORMAL)
552 exceptions |= FPSCR_IDC; 723 exceptions |= FPSCR_IDC;
553 724
554 if (tm & VFP_NAN) 725 if (tm & VFP_NAN)
555 vdm.sign = 0; 726 vdm.sign = 0;
556 727
557 if (vdm.exponent >= 1023 + 32) { 728 if (vdm.exponent >= 1023 + 32) {
558 d = vdm.sign ? 0 : 0xffffffff; 729 d = vdm.sign ? 0 : 0xffffffff;
559 exceptions = FPSCR_IOC; 730 exceptions = FPSCR_IOC;
560 } else if (vdm.exponent >= 1023 - 1) { 731 } else if (vdm.exponent >= 1023 - 1) {
561 int shift = 1023 + 63 - vdm.exponent; 732 int shift = 1023 + 63 - vdm.exponent;
562 u64 rem, incr = 0; 733 u64 rem, incr = 0;
563 734
564 /* 735 /*
565 * 2^0 <= m < 2^32-2^8 736 * 2^0 <= m < 2^32-2^8
566 */ 737 */
567 d = (vdm.significand << 1) >> shift; 738 d = (ARMword)((vdm.significand << 1) >> shift);
568 rem = vdm.significand << (65 - shift); 739 rem = vdm.significand << (65 - shift);
569 740
570 if (rmode == FPSCR_ROUND_NEAREST) { 741 if (rmode == FPSCR_ROUND_NEAREST) {
571 incr = 0x8000000000000000ULL; 742 incr = 0x8000000000000000ULL;
572 if ((d & 1) == 0) 743 if ((d & 1) == 0)
573 incr -= 1; 744 incr -= 1;
574 } else if (rmode == FPSCR_ROUND_TOZERO) { 745 } else if (rmode == FPSCR_ROUND_TOZERO) {
575 incr = 0; 746 incr = 0;
576 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) { 747 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) {
577 incr = ~0ULL; 748 incr = ~0ULL;
578 } 749 }
579 750
580 if ((rem + incr) < rem) { 751 if ((rem + incr) < rem) {
581 if (d < 0xffffffff) 752 if (d < 0xffffffff)
582 d += 1; 753 d += 1;
583 else 754 else
584 exceptions |= FPSCR_IOC; 755 exceptions |= FPSCR_IOC;
585 } 756 }
586 757
587 if (d && vdm.sign) { 758 if (d && vdm.sign) {
588 d = 0; 759 d = 0;
589 exceptions |= FPSCR_IOC; 760 exceptions |= FPSCR_IOC;
590 } else if (rem) 761 } else if (rem)
591 exceptions |= FPSCR_IXC; 762 exceptions |= FPSCR_IXC;
592 } else { 763 } else {
593 d = 0; 764 d = 0;
594 if (vdm.exponent | vdm.significand) { 765 if (vdm.exponent | vdm.significand) {
595 exceptions |= FPSCR_IXC; 766 exceptions |= FPSCR_IXC;
596 if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) 767 if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0)
597 d = 1; 768 d = 1;
598 else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { 769 else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) {
599 d = 0; 770 d = 0;
600 exceptions |= FPSCR_IOC; 771 exceptions |= FPSCR_IOC;
601 } 772 }
602 } 773 }
603 } 774 }
604 775
605 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 776 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
606 777
607 vfp_put_float(state, d, sd); 778 vfp_put_float(state, d, sd);
608 779
609 return exceptions; 780 return exceptions;
610} 781}
611 782
612static u32 vfp_double_ftouiz(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) 783static u32 vfp_double_ftouiz(ARMul_State* state, int sd, int unused, int dm, u32 fpscr)
613{ 784{
614 pr_debug("In %s\n", __FUNCTION__); 785 pr_debug("In %s\n", __FUNCTION__);
615 return vfp_double_ftoui(state, sd, unused, dm, FPSCR_ROUND_TOZERO); 786 return vfp_double_ftoui(state, sd, unused, dm, FPSCR_ROUND_TOZERO);
616} 787}
617 788
618static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) 789static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 fpscr)
619{ 790{
620 struct vfp_double vdm; 791 struct vfp_double vdm;
621 u32 d, exceptions = 0; 792 u32 d, exceptions = 0;
622 int rmode = fpscr & FPSCR_RMODE_MASK; 793 int rmode = fpscr & FPSCR_RMODE_MASK;
623 int tm; 794 int tm;
624 795
625 pr_debug("In %s\n", __FUNCTION__); 796 pr_debug("In %s\n", __FUNCTION__);
626 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 797 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
627 vfp_double_dump("VDM", &vdm); 798 vfp_double_dump("VDM", &vdm);
628 799
629 /* 800 /*
630 * Do we have denormalised number? 801 * Do we have denormalised number?
631 */ 802 */
632 tm = vfp_double_type(&vdm); 803 tm = vfp_double_type(&vdm);
633 if (tm & VFP_DENORMAL) 804 if (tm & VFP_DENORMAL)
634 exceptions |= FPSCR_IDC; 805 exceptions |= FPSCR_IDC;
635 806
636 if (tm & VFP_NAN) { 807 if (tm & VFP_NAN) {
637 d = 0; 808 d = 0;
638 exceptions |= FPSCR_IOC; 809 exceptions |= FPSCR_IOC;
639 } else if (vdm.exponent >= 1023 + 32) { 810 } else if (vdm.exponent >= 1023 + 32) {
640 d = 0x7fffffff; 811 d = 0x7fffffff;
641 if (vdm.sign) 812 if (vdm.sign)
642 d = ~d; 813 d = ~d;
643 exceptions |= FPSCR_IOC; 814 exceptions |= FPSCR_IOC;
644 } else if (vdm.exponent >= 1023 - 1) { 815 } else if (vdm.exponent >= 1023 - 1) {
645 int shift = 1023 + 63 - vdm.exponent; /* 58 */ 816 int shift = 1023 + 63 - vdm.exponent; /* 58 */
646 u64 rem, incr = 0; 817 u64 rem, incr = 0;
647 818
648 d = (vdm.significand << 1) >> shift; 819 d = (ARMword)((vdm.significand << 1) >> shift);
649 rem = vdm.significand << (65 - shift); 820 rem = vdm.significand << (65 - shift);
650 821
651 if (rmode == FPSCR_ROUND_NEAREST) { 822 if (rmode == FPSCR_ROUND_NEAREST) {
652 incr = 0x8000000000000000ULL; 823 incr = 0x8000000000000000ULL;
653 if ((d & 1) == 0) 824 if ((d & 1) == 0)
654 incr -= 1; 825 incr -= 1;
655 } else if (rmode == FPSCR_ROUND_TOZERO) { 826 } else if (rmode == FPSCR_ROUND_TOZERO) {
656 incr = 0; 827 incr = 0;
657 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) { 828 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) {
658 incr = ~0ULL; 829 incr = ~0ULL;
659 } 830 }
660 831
661 if ((rem + incr) < rem && d < 0xffffffff) 832 if ((rem + incr) < rem && d < 0xffffffff)
662 d += 1; 833 d += 1;
663 if (d > 0x7fffffff + (vdm.sign != 0)) { 834 if (d > (0x7fffffff + (vdm.sign != 0))) {
664 d = 0x7fffffff + (vdm.sign != 0); 835 d = (0x7fffffff + (vdm.sign != 0));
665 exceptions |= FPSCR_IOC; 836 exceptions |= FPSCR_IOC;
666 } else if (rem) 837 } else if (rem)
667 exceptions |= FPSCR_IXC; 838 exceptions |= FPSCR_IXC;
668 839
669 if (vdm.sign) 840 if (vdm.sign)
670 d = -d; 841 d = -d;
671 } else { 842 } else {
672 d = 0; 843 d = 0;
673 if (vdm.exponent | vdm.significand) { 844 if (vdm.exponent | vdm.significand) {
674 exceptions |= FPSCR_IXC; 845 exceptions |= FPSCR_IXC;
675 if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) 846 if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0)
676 d = 1; 847 d = 1;
677 else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) 848 else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign)
678 d = -1; 849 d = -1;
679 } 850 }
680 } 851 }
681 852
682 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 853 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
683 854
684 vfp_put_float(state, (s32)d, sd); 855 vfp_put_float(state, (s32)d, sd);
685 856
686 return exceptions; 857 return exceptions;
687} 858}
688 859
689static u32 vfp_double_ftosiz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) 860static u32 vfp_double_ftosiz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr)
690{ 861{
691 pr_debug("In %s\n", __FUNCTION__); 862 pr_debug("In %s\n", __FUNCTION__);
692 return vfp_double_ftosi(state, dd, unused, dm, FPSCR_ROUND_TOZERO); 863 return vfp_double_ftosi(state, dd, unused, dm, FPSCR_ROUND_TOZERO);
693} 864}
694 865
695static struct op fops_ext[] = { 866static struct op fops_ext[] = {
@@ -728,197 +899,195 @@ static struct op fops_ext[] = {
728 899
729static u32 900static u32
730vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn, 901vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn,
731 struct vfp_double *vdm, u32 fpscr) 902 struct vfp_double *vdm, u32 fpscr)
732{ 903{
733 struct vfp_double *vdp; 904 struct vfp_double *vdp;
734 u32 exceptions = 0; 905 u32 exceptions = 0;
735 int tn, tm; 906 int tn, tm;
736 907
737 tn = vfp_double_type(vdn); 908 tn = vfp_double_type(vdn);
738 tm = vfp_double_type(vdm); 909 tm = vfp_double_type(vdm);
739 910
740 if (tn & tm & VFP_INFINITY) { 911 if (tn & tm & VFP_INFINITY) {
741 /* 912 /*
742 * Two infinities. Are they different signs? 913 * Two infinities. Are they different signs?
743 */ 914 */
744 if (vdn->sign ^ vdm->sign) { 915 if (vdn->sign ^ vdm->sign) {
745 /* 916 /*
746 * different signs -> invalid 917 * different signs -> invalid
747 */ 918 */
748 exceptions = FPSCR_IOC; 919 exceptions = FPSCR_IOC;
749 vdp = &vfp_double_default_qnan; 920 vdp = &vfp_double_default_qnan;
750 } else { 921 } else {
751 /* 922 /*
752 * same signs -> valid 923 * same signs -> valid
753 */ 924 */
754 vdp = vdn; 925 vdp = vdn;
755 } 926 }
756 } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) { 927 } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) {
757 /* 928 /*
758 * One infinity and one number -> infinity 929 * One infinity and one number -> infinity
759 */ 930 */
760 vdp = vdn; 931 vdp = vdn;
761 } else { 932 } else {
762 /* 933 /*
763 * 'n' is a NaN of some type 934 * 'n' is a NaN of some type
764 */ 935 */
765 return vfp_propagate_nan(vdd, vdn, vdm, fpscr); 936 return vfp_propagate_nan(vdd, vdn, vdm, fpscr);
766 } 937 }
767 *vdd = *vdp; 938 *vdd = *vdp;
768 return exceptions; 939 return exceptions;
769} 940}
770 941
771static u32 942u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,struct vfp_double *vdm, u32 fpscr)
772vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,
773 struct vfp_double *vdm, u32 fpscr)
774{ 943{
775 u32 exp_diff; 944 u32 exp_diff;
776 u64 m_sig; 945 u64 m_sig;
777 946
778 if (vdn->significand & (1ULL << 63) || 947 if (vdn->significand & (1ULL << 63) ||
779 vdm->significand & (1ULL << 63)) { 948 vdm->significand & (1ULL << 63)) {
780 pr_info("VFP: bad FP values\n"); 949 pr_info("VFP: bad FP values in %s\n", __func__);
781 vfp_double_dump("VDN", vdn); 950 vfp_double_dump("VDN", vdn);
782 vfp_double_dump("VDM", vdm); 951 vfp_double_dump("VDM", vdm);
783 } 952 }
784 953
785 /* 954 /*
786 * Ensure that 'n' is the largest magnitude number. Note that 955 * Ensure that 'n' is the largest magnitude number. Note that
787 * if 'n' and 'm' have equal exponents, we do not swap them. 956 * if 'n' and 'm' have equal exponents, we do not swap them.
788 * This ensures that NaN propagation works correctly. 957 * This ensures that NaN propagation works correctly.
789 */ 958 */
790 if (vdn->exponent < vdm->exponent) { 959 if (vdn->exponent < vdm->exponent) {
791 struct vfp_double *t = vdn; 960 struct vfp_double *t = vdn;
792 vdn = vdm; 961 vdn = vdm;
793 vdm = t; 962 vdm = t;
794 } 963 }
795 964
796 /* 965 /*
797 * Is 'n' an infinity or a NaN? Note that 'm' may be a number, 966 * Is 'n' an infinity or a NaN? Note that 'm' may be a number,
798 * infinity or a NaN here. 967 * infinity or a NaN here.
799 */ 968 */
800 if (vdn->exponent == 2047) 969 if (vdn->exponent == 2047)
801 return vfp_double_fadd_nonnumber(vdd, vdn, vdm, fpscr); 970 return vfp_double_fadd_nonnumber(vdd, vdn, vdm, fpscr);
802 971
803 /* 972 /*
804 * We have two proper numbers, where 'vdn' is the larger magnitude. 973 * We have two proper numbers, where 'vdn' is the larger magnitude.
805 * 974 *
806 * Copy 'n' to 'd' before doing the arithmetic. 975 * Copy 'n' to 'd' before doing the arithmetic.
807 */ 976 */
808 *vdd = *vdn; 977 *vdd = *vdn;
809 978
810 /* 979 /*
811 * Align 'm' with the result. 980 * Align 'm' with the result.
812 */ 981 */
813 exp_diff = vdn->exponent - vdm->exponent; 982 exp_diff = vdn->exponent - vdm->exponent;
814 m_sig = vfp_shiftright64jamming(vdm->significand, exp_diff); 983 m_sig = vfp_shiftright64jamming(vdm->significand, exp_diff);
815 984
816 /* 985 /*
817 * If the signs are different, we are really subtracting. 986 * If the signs are different, we are really subtracting.
818 */ 987 */
819 if (vdn->sign ^ vdm->sign) { 988 if (vdn->sign ^ vdm->sign) {
820 m_sig = vdn->significand - m_sig; 989 m_sig = vdn->significand - m_sig;
821 if ((s64)m_sig < 0) { 990 if ((s64)m_sig < 0) {
822 vdd->sign = vfp_sign_negate(vdd->sign); 991 vdd->sign = vfp_sign_negate(vdd->sign);
823 m_sig = -m_sig; 992 m_sig = -m_sig;
824 } else if (m_sig == 0) { 993 } else if (m_sig == 0) {
825 vdd->sign = (fpscr & FPSCR_RMODE_MASK) == 994 vdd->sign = (fpscr & FPSCR_RMODE_MASK) ==
826 FPSCR_ROUND_MINUSINF ? 0x8000 : 0; 995 FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
827 } 996 }
828 } else { 997 } else {
829 m_sig += vdn->significand; 998 m_sig += vdn->significand;
830 } 999 }
831 vdd->significand = m_sig; 1000 vdd->significand = m_sig;
832 1001
833 return 0; 1002 return 0;
834} 1003}
835 1004
836static u32 1005u32
837vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, 1006vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn,
838 struct vfp_double *vdm, u32 fpscr) 1007 struct vfp_double *vdm, u32 fpscr)
839{ 1008{
840 vfp_double_dump("VDN", vdn); 1009 vfp_double_dump("VDN", vdn);
841 vfp_double_dump("VDM", vdm); 1010 vfp_double_dump("VDM", vdm);
842 1011
843 /* 1012 /*
844 * Ensure that 'n' is the largest magnitude number. Note that 1013 * Ensure that 'n' is the largest magnitude number. Note that
845 * if 'n' and 'm' have equal exponents, we do not swap them. 1014 * if 'n' and 'm' have equal exponents, we do not swap them.
846 * This ensures that NaN propagation works correctly. 1015 * This ensures that NaN propagation works correctly.
847 */ 1016 */
848 if (vdn->exponent < vdm->exponent) { 1017 if (vdn->exponent < vdm->exponent) {
849 struct vfp_double *t = vdn; 1018 struct vfp_double *t = vdn;
850 vdn = vdm; 1019 vdn = vdm;
851 vdm = t; 1020 vdm = t;
852 pr_debug("VFP: swapping M <-> N\n"); 1021 pr_debug("VFP: swapping M <-> N\n");
853 } 1022 }
854 1023
855 vdd->sign = vdn->sign ^ vdm->sign; 1024 vdd->sign = vdn->sign ^ vdm->sign;
856 1025
857 /* 1026 /*
858 * If 'n' is an infinity or NaN, handle it. 'm' may be anything. 1027 * If 'n' is an infinity or NaN, handle it. 'm' may be anything.
859 */ 1028 */
860 if (vdn->exponent == 2047) { 1029 if (vdn->exponent == 2047) {
861 if (vdn->significand || (vdm->exponent == 2047 && vdm->significand)) 1030 if (vdn->significand || (vdm->exponent == 2047 && vdm->significand))
862 return vfp_propagate_nan(vdd, vdn, vdm, fpscr); 1031 return vfp_propagate_nan(vdd, vdn, vdm, fpscr);
863 if ((vdm->exponent | vdm->significand) == 0) { 1032 if ((vdm->exponent | vdm->significand) == 0) {
864 *vdd = vfp_double_default_qnan; 1033 *vdd = vfp_double_default_qnan;
865 return FPSCR_IOC; 1034 return FPSCR_IOC;
866 } 1035 }
867 vdd->exponent = vdn->exponent; 1036 vdd->exponent = vdn->exponent;
868 vdd->significand = 0; 1037 vdd->significand = 0;
869 return 0; 1038 return 0;
870 } 1039 }
871 1040
872 /* 1041 /*
873 * If 'm' is zero, the result is always zero. In this case, 1042 * If 'm' is zero, the result is always zero. In this case,
874 * 'n' may be zero or a number, but it doesn't matter which. 1043 * 'n' may be zero or a number, but it doesn't matter which.
875 */ 1044 */
876 if ((vdm->exponent | vdm->significand) == 0) { 1045 if ((vdm->exponent | vdm->significand) == 0) {
877 vdd->exponent = 0; 1046 vdd->exponent = 0;
878 vdd->significand = 0; 1047 vdd->significand = 0;
879 return 0; 1048 return 0;
880 } 1049 }
881 1050
882 /* 1051 /*
883 * We add 2 to the destination exponent for the same reason 1052 * We add 2 to the destination exponent for the same reason
884 * as the addition case - though this time we have +1 from 1053 * as the addition case - though this time we have +1 from
885 * each input operand. 1054 * each input operand.
886 */ 1055 */
887 vdd->exponent = vdn->exponent + vdm->exponent - 1023 + 2; 1056 vdd->exponent = vdn->exponent + vdm->exponent - 1023 + 2;
888 vdd->significand = vfp_hi64multiply64(vdn->significand, vdm->significand); 1057 vdd->significand = vfp_hi64multiply64(vdn->significand, vdm->significand);
889 1058
890 vfp_double_dump("VDD", vdd); 1059 vfp_double_dump("VDD", vdd);
891 return 0; 1060 return 0;
892} 1061}
893 1062
894#define NEG_MULTIPLY (1 << 0) 1063#define NEG_MULTIPLY (1 << 0)
895#define NEG_SUBTRACT (1 << 1) 1064#define NEG_SUBTRACT (1 << 1)
896 1065
897static u32 1066static u32
898vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 fpscr, u32 negate, const char *func) 1067vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 fpscr, u32 negate, char *func)
899{ 1068{
900 struct vfp_double vdd, vdp, vdn, vdm; 1069 struct vfp_double vdd, vdp, vdn, vdm;
901 u32 exceptions; 1070 u32 exceptions;
902 1071
903 vfp_double_unpack(&vdn, vfp_get_double(state, dn)); 1072 vfp_double_unpack(&vdn, vfp_get_double(state, dn));
904 if (vdn.exponent == 0 && vdn.significand) 1073 if (vdn.exponent == 0 && vdn.significand)
905 vfp_double_normalise_denormal(&vdn); 1074 vfp_double_normalise_denormal(&vdn);
906 1075
907 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 1076 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
908 if (vdm.exponent == 0 && vdm.significand) 1077 if (vdm.exponent == 0 && vdm.significand)
909 vfp_double_normalise_denormal(&vdm); 1078 vfp_double_normalise_denormal(&vdm);
910 1079
911 exceptions = vfp_double_multiply(&vdp, &vdn, &vdm, fpscr); 1080 exceptions = vfp_double_multiply(&vdp, &vdn, &vdm, fpscr);
912 if (negate & NEG_MULTIPLY) 1081 if (negate & NEG_MULTIPLY)
913 vdp.sign = vfp_sign_negate(vdp.sign); 1082 vdp.sign = vfp_sign_negate(vdp.sign);
914 1083
915 vfp_double_unpack(&vdn, vfp_get_double(state, dd)); 1084 vfp_double_unpack(&vdn, vfp_get_double(state, dd));
916 if (negate & NEG_SUBTRACT) 1085 if (negate & NEG_SUBTRACT)
917 vdn.sign = vfp_sign_negate(vdn.sign); 1086 vdn.sign = vfp_sign_negate(vdn.sign);
918 1087
919 exceptions |= vfp_double_add(&vdd, &vdn, &vdp, fpscr); 1088 exceptions |= vfp_double_add(&vdd, &vdn, &vdp, fpscr);
920 1089
921 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, func); 1090 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, func);
922} 1091}
923 1092
924/* 1093/*
@@ -930,8 +1099,8 @@ vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 f
930 */ 1099 */
931static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1100static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
932{ 1101{
933 pr_debug("In %s\n", __FUNCTION__); 1102 pr_debug("In %s\n", __FUNCTION__);
934 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, 0, "fmac"); 1103 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, 0, "fmac");
935} 1104}
936 1105
937/* 1106/*
@@ -939,8 +1108,8 @@ static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr
939 */ 1108 */
940static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1109static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
941{ 1110{
942 pr_debug("In %s\n", __FUNCTION__); 1111 pr_debug("In %s\n", __FUNCTION__);
943 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac"); 1112 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac");
944} 1113}
945 1114
946/* 1115/*
@@ -948,8 +1117,8 @@ static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpsc
948 */ 1117 */
949static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1118static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
950{ 1119{
951 pr_debug("In %s\n", __FUNCTION__); 1120 pr_debug("In %s\n", __FUNCTION__);
952 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc"); 1121 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc");
953} 1122}
954 1123
955/* 1124/*
@@ -957,8 +1126,8 @@ static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr
957 */ 1126 */
958static u32 vfp_double_fnmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1127static u32 vfp_double_fnmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
959{ 1128{
960 pr_debug("In %s\n", __FUNCTION__); 1129 pr_debug("In %s\n", __FUNCTION__);
961 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); 1130 return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc");
962} 1131}
963 1132
964/* 1133/*
@@ -966,20 +1135,20 @@ static u32 vfp_double_fnmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpsc
966 */ 1135 */
967static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1136static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
968{ 1137{
969 struct vfp_double vdd, vdn, vdm; 1138 struct vfp_double vdd, vdn, vdm;
970 u32 exceptions; 1139 u32 exceptions;
971 1140
972 pr_debug("In %s\n", __FUNCTION__); 1141 pr_debug("In %s\n", __FUNCTION__);
973 vfp_double_unpack(&vdn, vfp_get_double(state, dn)); 1142 vfp_double_unpack(&vdn, vfp_get_double(state, dn));
974 if (vdn.exponent == 0 && vdn.significand) 1143 if (vdn.exponent == 0 && vdn.significand)
975 vfp_double_normalise_denormal(&vdn); 1144 vfp_double_normalise_denormal(&vdn);
976 1145
977 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 1146 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
978 if (vdm.exponent == 0 && vdm.significand) 1147 if (vdm.exponent == 0 && vdm.significand)
979 vfp_double_normalise_denormal(&vdm); 1148 vfp_double_normalise_denormal(&vdm);
980 1149
981 exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr); 1150 exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr);
982 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fmul"); 1151 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fmul");
983} 1152}
984 1153
985/* 1154/*
@@ -987,22 +1156,22 @@ static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr
987 */ 1156 */
988static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1157static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
989{ 1158{
990 struct vfp_double vdd, vdn, vdm; 1159 struct vfp_double vdd, vdn, vdm;
991 u32 exceptions; 1160 u32 exceptions;
992 1161
993 pr_debug("In %s\n", __FUNCTION__); 1162 pr_debug("In %s\n", __FUNCTION__);
994 vfp_double_unpack(&vdn, vfp_get_double(state, dn)); 1163 vfp_double_unpack(&vdn, vfp_get_double(state, dn));
995 if (vdn.exponent == 0 && vdn.significand) 1164 if (vdn.exponent == 0 && vdn.significand)
996 vfp_double_normalise_denormal(&vdn); 1165 vfp_double_normalise_denormal(&vdn);
997 1166
998 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 1167 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
999 if (vdm.exponent == 0 && vdm.significand) 1168 if (vdm.exponent == 0 && vdm.significand)
1000 vfp_double_normalise_denormal(&vdm); 1169 vfp_double_normalise_denormal(&vdm);
1001 1170
1002 exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr); 1171 exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr);
1003 vdd.sign = vfp_sign_negate(vdd.sign); 1172 vdd.sign = vfp_sign_negate(vdd.sign);
1004 1173
1005 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fnmul"); 1174 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fnmul");
1006} 1175}
1007 1176
1008/* 1177/*
@@ -1010,21 +1179,21 @@ static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpsc
1010 */ 1179 */
1011static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1180static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
1012{ 1181{
1013 struct vfp_double vdd, vdn, vdm; 1182 struct vfp_double vdd, vdn, vdm;
1014 u32 exceptions; 1183 u32 exceptions;
1015 1184
1016 pr_debug("In %s\n", __FUNCTION__); 1185 pr_debug("In %s\n", __FUNCTION__);
1017 vfp_double_unpack(&vdn, vfp_get_double(state, dn)); 1186 vfp_double_unpack(&vdn, vfp_get_double(state, dn));
1018 if (vdn.exponent == 0 && vdn.significand) 1187 if (vdn.exponent == 0 && vdn.significand)
1019 vfp_double_normalise_denormal(&vdn); 1188 vfp_double_normalise_denormal(&vdn);
1020 1189
1021 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 1190 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
1022 if (vdm.exponent == 0 && vdm.significand) 1191 if (vdm.exponent == 0 && vdm.significand)
1023 vfp_double_normalise_denormal(&vdm); 1192 vfp_double_normalise_denormal(&vdm);
1024 1193
1025 exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr); 1194 exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr);
1026 1195
1027 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fadd"); 1196 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fadd");
1028} 1197}
1029 1198
1030/* 1199/*
@@ -1032,26 +1201,26 @@ static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr
1032 */ 1201 */
1033static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1202static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
1034{ 1203{
1035 struct vfp_double vdd, vdn, vdm; 1204 struct vfp_double vdd, vdn, vdm;
1036 u32 exceptions; 1205 u32 exceptions;
1037 1206
1038 pr_debug("In %s\n", __FUNCTION__); 1207 pr_debug("In %s\n", __FUNCTION__);
1039 vfp_double_unpack(&vdn, vfp_get_double(state, dn)); 1208 vfp_double_unpack(&vdn, vfp_get_double(state, dn));
1040 if (vdn.exponent == 0 && vdn.significand) 1209 if (vdn.exponent == 0 && vdn.significand)
1041 vfp_double_normalise_denormal(&vdn); 1210 vfp_double_normalise_denormal(&vdn);
1042 1211
1043 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 1212 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
1044 if (vdm.exponent == 0 && vdm.significand) 1213 if (vdm.exponent == 0 && vdm.significand)
1045 vfp_double_normalise_denormal(&vdm); 1214 vfp_double_normalise_denormal(&vdm);
1046 1215
1047 /* 1216 /*
1048 * Subtraction is like addition, but with a negated operand. 1217 * Subtraction is like addition, but with a negated operand.
1049 */ 1218 */
1050 vdm.sign = vfp_sign_negate(vdm.sign); 1219 vdm.sign = vfp_sign_negate(vdm.sign);
1051 1220
1052 exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr); 1221 exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr);
1053 1222
1054 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fsub"); 1223 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fsub");
1055} 1224}
1056 1225
1057/* 1226/*
@@ -1059,120 +1228,120 @@ static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr
1059 */ 1228 */
1060static u32 vfp_double_fdiv(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) 1229static u32 vfp_double_fdiv(ARMul_State* state, int dd, int dn, int dm, u32 fpscr)
1061{ 1230{
1062 struct vfp_double vdd, vdn, vdm; 1231 struct vfp_double vdd, vdn, vdm;
1063 u32 exceptions = 0; 1232 u32 exceptions = 0;
1064 int tm, tn; 1233 int tm, tn;
1065 1234
1066 pr_debug("In %s\n", __FUNCTION__); 1235 pr_debug("In %s\n", __FUNCTION__);
1067 vfp_double_unpack(&vdn, vfp_get_double(state, dn)); 1236 vfp_double_unpack(&vdn, vfp_get_double(state, dn));
1068 vfp_double_unpack(&vdm, vfp_get_double(state, dm)); 1237 vfp_double_unpack(&vdm, vfp_get_double(state, dm));
1069 1238
1070 vdd.sign = vdn.sign ^ vdm.sign; 1239 vdd.sign = vdn.sign ^ vdm.sign;
1071 1240
1072 tn = vfp_double_type(&vdn); 1241 tn = vfp_double_type(&vdn);
1073 tm = vfp_double_type(&vdm); 1242 tm = vfp_double_type(&vdm);
1074 1243
1075 /* 1244 /*
1076 * Is n a NAN? 1245 * Is n a NAN?
1077 */ 1246 */
1078 if (tn & VFP_NAN) 1247 if (tn & VFP_NAN)
1079 goto vdn_nan; 1248 goto vdn_nan;
1080 1249
1081 /* 1250 /*
1082 * Is m a NAN? 1251 * Is m a NAN?
1083 */ 1252 */
1084 if (tm & VFP_NAN) 1253 if (tm & VFP_NAN)
1085 goto vdm_nan; 1254 goto vdm_nan;
1086 1255
1087 /* 1256 /*
1088 * If n and m are infinity, the result is invalid 1257 * If n and m are infinity, the result is invalid
1089 * If n and m are zero, the result is invalid 1258 * If n and m are zero, the result is invalid
1090 */ 1259 */
1091 if (tm & tn & (VFP_INFINITY|VFP_ZERO)) 1260 if (tm & tn & (VFP_INFINITY|VFP_ZERO))
1092 goto invalid; 1261 goto invalid;
1093 1262
1094 /* 1263 /*
1095 * If n is infinity, the result is infinity 1264 * If n is infinity, the result is infinity
1096 */ 1265 */
1097 if (tn & VFP_INFINITY) 1266 if (tn & VFP_INFINITY)
1098 goto infinity; 1267 goto infinity;
1099 1268
1100 /* 1269 /*
1101 * If m is zero, raise div0 exceptions 1270 * If m is zero, raise div0 exceptions
1102 */ 1271 */
1103 if (tm & VFP_ZERO) 1272 if (tm & VFP_ZERO)
1104 goto divzero; 1273 goto divzero;
1105 1274
1106 /* 1275 /*
1107 * If m is infinity, or n is zero, the result is zero 1276 * If m is infinity, or n is zero, the result is zero
1108 */ 1277 */
1109 if (tm & VFP_INFINITY || tn & VFP_ZERO) 1278 if (tm & VFP_INFINITY || tn & VFP_ZERO)
1110 goto zero; 1279 goto zero;
1111 1280
1112 if (tn & VFP_DENORMAL) 1281 if (tn & VFP_DENORMAL)
1113 vfp_double_normalise_denormal(&vdn); 1282 vfp_double_normalise_denormal(&vdn);
1114 if (tm & VFP_DENORMAL) 1283 if (tm & VFP_DENORMAL)
1115 vfp_double_normalise_denormal(&vdm); 1284 vfp_double_normalise_denormal(&vdm);
1116 1285
1117 /* 1286 /*
1118 * Ok, we have two numbers, we can perform division. 1287 * Ok, we have two numbers, we can perform division.
1119 */ 1288 */
1120 vdd.exponent = vdn.exponent - vdm.exponent + 1023 - 1; 1289 vdd.exponent = vdn.exponent - vdm.exponent + 1023 - 1;
1121 vdm.significand <<= 1; 1290 vdm.significand <<= 1;
1122 if (vdm.significand <= (2 * vdn.significand)) { 1291 if (vdm.significand <= (2 * vdn.significand)) {
1123 vdn.significand >>= 1; 1292 vdn.significand >>= 1;
1124 vdd.exponent++; 1293 vdd.exponent++;
1125 } 1294 }
1126 vdd.significand = vfp_estimate_div128to64(vdn.significand, 0, vdm.significand); 1295 vdd.significand = vfp_estimate_div128to64(vdn.significand, 0, vdm.significand);
1127 if ((vdd.significand & 0x1ff) <= 2) { 1296 if ((vdd.significand & 0x1ff) <= 2) {
1128 u64 termh, terml, remh, reml; 1297 u64 termh, terml, remh, reml;
1129 mul64to128(&termh, &terml, vdm.significand, vdd.significand); 1298 mul64to128(&termh, &terml, vdm.significand, vdd.significand);
1130 sub128(&remh, &reml, vdn.significand, 0, termh, terml); 1299 sub128(&remh, &reml, vdn.significand, 0, termh, terml);
1131 while ((s64)remh < 0) { 1300 while ((s64)remh < 0) {
1132 vdd.significand -= 1; 1301 vdd.significand -= 1;
1133 add128(&remh, &reml, remh, reml, 0, vdm.significand); 1302 add128(&remh, &reml, remh, reml, 0, vdm.significand);
1134 } 1303 }
1135 vdd.significand |= (reml != 0); 1304 vdd.significand |= (reml != 0);
1136 } 1305 }
1137 return vfp_double_normaliseround(state, dd, &vdd, fpscr, 0, "fdiv"); 1306 return vfp_double_normaliseround(state, dd, &vdd, fpscr, 0, "fdiv");
1138 1307
1139 vdn_nan: 1308vdn_nan:
1140 exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr); 1309 exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr);
1141 pack: 1310pack:
1142 vfp_put_double(state, vfp_double_pack(&vdd), dd); 1311 vfp_put_double(state, vfp_double_pack(&vdd), dd);
1143 return exceptions; 1312 return exceptions;
1144 1313
1145 vdm_nan: 1314vdm_nan:
1146 exceptions = vfp_propagate_nan(&vdd, &vdm, &vdn, fpscr); 1315 exceptions = vfp_propagate_nan(&vdd, &vdm, &vdn, fpscr);
1147 goto pack; 1316 goto pack;
1148 1317
1149 zero: 1318zero:
1150 vdd.exponent = 0; 1319 vdd.exponent = 0;
1151 vdd.significand = 0; 1320 vdd.significand = 0;
1152 goto pack; 1321 goto pack;
1153 1322
1154 divzero: 1323divzero:
1155 exceptions = FPSCR_DZC; 1324 exceptions = FPSCR_DZC;
1156 infinity: 1325infinity:
1157 vdd.exponent = 2047; 1326 vdd.exponent = 2047;
1158 vdd.significand = 0; 1327 vdd.significand = 0;
1159 goto pack; 1328 goto pack;
1160 1329
1161 invalid: 1330invalid:
1162 vfp_put_double(state, vfp_double_pack(&vfp_double_default_qnan), dd); 1331 vfp_put_double(state, vfp_double_pack(&vfp_double_default_qnan), dd);
1163 return FPSCR_IOC; 1332 return FPSCR_IOC;
1164} 1333}
1165 1334
1166static struct op fops[] = { 1335static struct op fops[] = {
1167 { vfp_double_fmac, 0 }, 1336 { vfp_double_fmac, 0 },
1168 { vfp_double_fmsc, 0 }, 1337 { vfp_double_fmsc, 0 },
1169 { vfp_double_fmul, 0 }, 1338 { vfp_double_fmul, 0 },
1170 { vfp_double_fadd, 0 }, 1339 { vfp_double_fadd, 0 },
1171 { vfp_double_fnmac, 0 }, 1340 { vfp_double_fnmac, 0 },
1172 { vfp_double_fnmsc, 0 }, 1341 { vfp_double_fnmsc, 0 },
1173 { vfp_double_fnmul, 0 }, 1342 { vfp_double_fnmul, 0 },
1174 { vfp_double_fsub, 0 }, 1343 { vfp_double_fsub, 0 },
1175 { vfp_double_fdiv, 0 }, 1344 { vfp_double_fdiv, 0 },
1176}; 1345};
1177 1346
1178#define FREG_BANK(x) ((x) & 0x0c) 1347#define FREG_BANK(x) ((x) & 0x0c)
@@ -1180,84 +1349,84 @@ static struct op fops[] = {
1180 1349
1181u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) 1350u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr)
1182{ 1351{
1183 u32 op = inst & FOP_MASK; 1352 u32 op = inst & FOP_MASK;
1184 u32 exceptions = 0; 1353 u32 exceptions = 0;
1185 unsigned int dest; 1354 unsigned int dest;
1186 unsigned int dn = vfp_get_dn(inst); 1355 unsigned int dn = vfp_get_dn(inst);
1187 unsigned int dm; 1356 unsigned int dm;
1188 unsigned int vecitr, veclen, vecstride; 1357 unsigned int vecitr, veclen, vecstride;
1189 struct op *fop; 1358 struct op *fop;
1190 1359
1191 pr_debug("In %s\n", __FUNCTION__); 1360 pr_debug("In %s\n", __FUNCTION__);
1192 vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)); 1361 vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK));
1193 1362
1194 fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; 1363 fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
1195 1364
1196 /* 1365 /*
1197 * fcvtds takes an sN register number as destination, not dN. 1366 * fcvtds takes an sN register number as destination, not dN.
1198 * It also always operates on scalars. 1367 * It also always operates on scalars.
1199 */ 1368 */
1200 if (fop->flags & OP_SD) 1369 if (fop->flags & OP_SD)
1201 dest = vfp_get_sd(inst); 1370 dest = vfp_get_sd(inst);
1202 else 1371 else
1203 dest = vfp_get_dd(inst); 1372 dest = vfp_get_dd(inst);
1204 1373
1205 /* 1374 /*
1206 * f[us]ito takes a sN operand, not a dN operand. 1375 * f[us]ito takes a sN operand, not a dN operand.
1207 */ 1376 */
1208 if (fop->flags & OP_SM) 1377 if (fop->flags & OP_SM)
1209 dm = vfp_get_sm(inst); 1378 dm = vfp_get_sm(inst);
1210 else 1379 else
1211 dm = vfp_get_dm(inst); 1380 dm = vfp_get_dm(inst);
1212 1381
1213 /* 1382 /*
1214 * If destination bank is zero, vector length is always '1'. 1383 * If destination bank is zero, vector length is always '1'.
1215 * ARM DDI0100F C5.1.3, C5.3.2. 1384 * ARM DDI0100F C5.1.3, C5.3.2.
1216 */ 1385 */
1217 if ((fop->flags & OP_SCALAR) || (FREG_BANK(dest) == 0)) 1386 if ((fop->flags & OP_SCALAR) || (FREG_BANK(dest) == 0))
1218 veclen = 0; 1387 veclen = 0;
1219 else 1388 else
1220 veclen = fpscr & FPSCR_LENGTH_MASK; 1389 veclen = fpscr & FPSCR_LENGTH_MASK;
1221 1390
1222 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1391 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
1223 (veclen >> FPSCR_LENGTH_BIT) + 1); 1392 (veclen >> FPSCR_LENGTH_BIT) + 1);
1224 1393
1225 if (!fop->fn) { 1394 if (!fop->fn) {
1226 printf("VFP: could not find double op %d\n", FEXT_TO_IDX(inst)); 1395 printf("VFP: could not find double op %d\n", FEXT_TO_IDX(inst));
1227 goto invalid; 1396 goto invalid;
1228 } 1397 }
1229 1398
1230 for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { 1399 for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
1231 u32 except; 1400 u32 except;
1232 char type; 1401 char type;
1233 1402
1234 type = fop->flags & OP_SD ? 's' : 'd'; 1403 type = fop->flags & OP_SD ? 's' : 'd';
1235 if (op == FOP_EXT) 1404 if (op == FOP_EXT)
1236 pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n", 1405 pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n",
1237 vecitr >> FPSCR_LENGTH_BIT, 1406 vecitr >> FPSCR_LENGTH_BIT,
1238 type, dest, dn, dm); 1407 type, dest, dn, dm);
1239 else 1408 else
1240 pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n", 1409 pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n",
1241 vecitr >> FPSCR_LENGTH_BIT, 1410 vecitr >> FPSCR_LENGTH_BIT,
1242 type, dest, dn, FOP_TO_IDX(op), dm); 1411 type, dest, dn, FOP_TO_IDX(op), dm);
1243 1412
1244 except = fop->fn(state, dest, dn, dm, fpscr); 1413 except = fop->fn(state, dest, dn, dm, fpscr);
1245 pr_debug("VFP: itr%d: exceptions=%08x\n", 1414 pr_debug("VFP: itr%d: exceptions=%08x\n",
1246 vecitr >> FPSCR_LENGTH_BIT, except); 1415 vecitr >> FPSCR_LENGTH_BIT, except);
1247 1416
1248 exceptions |= except; 1417 exceptions |= except;
1249 1418
1250 /* 1419 /*
1251 * CHECK: It appears to be undefined whether we stop when 1420 * CHECK: It appears to be undefined whether we stop when
1252 * we encounter an exception. We continue. 1421 * we encounter an exception. We continue.
1253 */ 1422 */
1254 dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 3); 1423 dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 3);
1255 dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 3); 1424 dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 3);
1256 if (FREG_BANK(dm) != 0) 1425 if (FREG_BANK(dm) != 0)
1257 dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 3); 1426 dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 3);
1258 } 1427 }
1259 return exceptions; 1428 return exceptions;
1260 1429
1261 invalid: 1430invalid:
1262 return ~0; 1431 return ~0;
1263} 1432}
diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
index 8bcbd4fe9..07d0c1f44 100644
--- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
@@ -56,167 +56,167 @@
56#include "core/arm/skyeye_common/vfp/vfp.h" 56#include "core/arm/skyeye_common/vfp/vfp.h"
57 57
58static struct vfp_single vfp_single_default_qnan = { 58static struct vfp_single vfp_single_default_qnan = {
59 //.exponent = 255, 59 255,
60 //.sign = 0, 60 0,
61 //.significand = VFP_SINGLE_SIGNIFICAND_QNAN, 61 VFP_SINGLE_SIGNIFICAND_QNAN,
62}; 62};
63 63
64static void vfp_single_dump(const char *str, struct vfp_single *s) 64static void vfp_single_dump(const char *str, struct vfp_single *s)
65{ 65{
66 pr_debug("VFP: %s: sign=%d exponent=%d significand=%08x\n", 66 pr_debug("VFP: %s: sign=%d exponent=%d significand=%08x\n",
67 str, s->sign != 0, s->exponent, s->significand); 67 str, s->sign != 0, s->exponent, s->significand);
68} 68}
69 69
70static void vfp_single_normalise_denormal(struct vfp_single *vs) 70static void vfp_single_normalise_denormal(struct vfp_single *vs)
71{ 71{
72 int bits = 31 - vfp_fls(vs->significand); 72 int bits = 31 - fls(vs->significand);
73 73
74 vfp_single_dump("normalise_denormal: in", vs); 74 vfp_single_dump("normalise_denormal: in", vs);
75 75
76 if (bits) { 76 if (bits) {
77 vs->exponent -= bits - 1; 77 vs->exponent -= bits - 1;
78 vs->significand <<= bits; 78 vs->significand <<= bits;
79 } 79 }
80 80
81 vfp_single_dump("normalise_denormal: out", vs); 81 vfp_single_dump("normalise_denormal: out", vs);
82} 82}
83 83
84 84
85u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func) 85u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func)
86{ 86{
87 u32 significand, incr, rmode; 87 u32 significand, incr, rmode;
88 int exponent, shift, underflow; 88 int exponent, shift, underflow;
89 89
90 vfp_single_dump("pack: in", vs); 90 vfp_single_dump("pack: in", vs);
91 91
92 /* 92 /*
93 * Infinities and NaNs are a special case. 93 * Infinities and NaNs are a special case.
94 */ 94 */
95 if (vs->exponent == 255 && (vs->significand == 0 || exceptions)) 95 if (vs->exponent == 255 && (vs->significand == 0 || exceptions))
96 goto pack; 96 goto pack;
97 97
98 /* 98 /*
99 * Special-case zero. 99 * Special-case zero.
100 */ 100 */
101 if (vs->significand == 0) { 101 if (vs->significand == 0) {
102 vs->exponent = 0; 102 vs->exponent = 0;
103 goto pack; 103 goto pack;
104 } 104 }
105 105
106 exponent = vs->exponent; 106 exponent = vs->exponent;
107 significand = vs->significand; 107 significand = vs->significand;
108 108
109 /* 109 /*
110 * Normalise first. Note that we shift the significand up to 110 * Normalise first. Note that we shift the significand up to
111 * bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least 111 * bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least
112 * significant bit. 112 * significant bit.
113 */ 113 */
114 shift = 32 - vfp_fls(significand); 114 shift = 32 - fls(significand);
115 if (shift < 32 && shift) { 115 if (shift < 32 && shift) {
116 exponent -= shift; 116 exponent -= shift;
117 significand <<= shift; 117 significand <<= shift;
118 } 118 }
119 119
120#if 1 120#if 1
121 vs->exponent = exponent; 121 vs->exponent = exponent;
122 vs->significand = significand; 122 vs->significand = significand;
123 vfp_single_dump("pack: normalised", vs); 123 vfp_single_dump("pack: normalised", vs);
124#endif 124#endif
125 125
126 /* 126 /*
127 * Tiny number? 127 * Tiny number?
128 */ 128 */
129 underflow = exponent < 0; 129 underflow = exponent < 0;
130 if (underflow) { 130 if (underflow) {
131 significand = vfp_shiftright32jamming(significand, -exponent); 131 significand = vfp_shiftright32jamming(significand, -exponent);
132 exponent = 0; 132 exponent = 0;
133#if 1 133#if 1
134 vs->exponent = exponent; 134 vs->exponent = exponent;
135 vs->significand = significand; 135 vs->significand = significand;
136 vfp_single_dump("pack: tiny number", vs); 136 vfp_single_dump("pack: tiny number", vs);
137#endif 137#endif
138 if (!(significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1))) 138 if (!(significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1)))
139 underflow = 0; 139 underflow = 0;
140 } 140 }
141 141
142 /* 142 /*
143 * Select rounding increment. 143 * Select rounding increment.
144 */ 144 */
145 incr = 0; 145 incr = 0;
146 rmode = fpscr & FPSCR_RMODE_MASK; 146 rmode = fpscr & FPSCR_RMODE_MASK;
147 147
148 if (rmode == FPSCR_ROUND_NEAREST) { 148 if (rmode == FPSCR_ROUND_NEAREST) {
149 incr = 1 << VFP_SINGLE_LOW_BITS; 149 incr = 1 << VFP_SINGLE_LOW_BITS;
150 if ((significand & (1 << (VFP_SINGLE_LOW_BITS + 1))) == 0) 150 if ((significand & (1 << (VFP_SINGLE_LOW_BITS + 1))) == 0)
151 incr -= 1; 151 incr -= 1;
152 } else if (rmode == FPSCR_ROUND_TOZERO) { 152 } else if (rmode == FPSCR_ROUND_TOZERO) {
153 incr = 0; 153 incr = 0;
154 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0)) 154 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0))
155 incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1; 155 incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1;
156 156
157 pr_debug("VFP: rounding increment = 0x%08x\n", incr); 157 pr_debug("VFP: rounding increment = 0x%08x\n", incr);
158 158
159 /* 159 /*
160 * Is our rounding going to overflow? 160 * Is our rounding going to overflow?
161 */ 161 */
162 if ((significand + incr) < significand) { 162 if ((significand + incr) < significand) {
163 exponent += 1; 163 exponent += 1;
164 significand = (significand >> 1) | (significand & 1); 164 significand = (significand >> 1) | (significand & 1);
165 incr >>= 1; 165 incr >>= 1;
166#if 1 166#if 1
167 vs->exponent = exponent; 167 vs->exponent = exponent;
168 vs->significand = significand; 168 vs->significand = significand;
169 vfp_single_dump("pack: overflow", vs); 169 vfp_single_dump("pack: overflow", vs);
170#endif 170#endif
171 } 171 }
172 172
173 /* 173 /*
174 * If any of the low bits (which will be shifted out of the 174 * If any of the low bits (which will be shifted out of the
175 * number) are non-zero, the result is inexact. 175 * number) are non-zero, the result is inexact.
176 */ 176 */
177 if (significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1)) 177 if (significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1))
178 exceptions |= FPSCR_IXC; 178 exceptions |= FPSCR_IXC;
179 179
180 /* 180 /*
181 * Do our rounding. 181 * Do our rounding.
182 */ 182 */
183 significand += incr; 183 significand += incr;
184 184
185 /* 185 /*
186 * Infinity? 186 * Infinity?
187 */ 187 */
188 if (exponent >= 254) { 188 if (exponent >= 254) {
189 exceptions |= FPSCR_OFC | FPSCR_IXC; 189 exceptions |= FPSCR_OFC | FPSCR_IXC;
190 if (incr == 0) { 190 if (incr == 0) {
191 vs->exponent = 253; 191 vs->exponent = 253;
192 vs->significand = 0x7fffffff; 192 vs->significand = 0x7fffffff;
193 } else { 193 } else {
194 vs->exponent = 255; /* infinity */ 194 vs->exponent = 255; /* infinity */
195 vs->significand = 0; 195 vs->significand = 0;
196 } 196 }
197 } else { 197 } else {
198 if (significand >> (VFP_SINGLE_LOW_BITS + 1) == 0) 198 if (significand >> (VFP_SINGLE_LOW_BITS + 1) == 0)
199 exponent = 0; 199 exponent = 0;
200 if (exponent || significand > 0x80000000) 200 if (exponent || significand > 0x80000000)
201 underflow = 0; 201 underflow = 0;
202 if (underflow) 202 if (underflow)
203 exceptions |= FPSCR_UFC; 203 exceptions |= FPSCR_UFC;
204 vs->exponent = exponent; 204 vs->exponent = exponent;
205 vs->significand = significand >> 1; 205 vs->significand = significand >> 1;
206 } 206 }
207 207
208 pack: 208pack:
209 vfp_single_dump("pack: final", vs); 209 vfp_single_dump("pack: final", vs);
210 { 210 {
211 s32 d = vfp_single_pack(vs); 211 s32 d = vfp_single_pack(vs);
212#if 1 212#if 1
213 pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, 213 pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func,
214 sd, d, exceptions); 214 sd, d, exceptions);
215#endif 215#endif
216 vfp_put_float(state, d, sd); 216 vfp_put_float(state, d, sd);
217 } 217 }
218 218
219 return exceptions; 219 return exceptions;
220} 220}
221 221
222/* 222/*
@@ -225,43 +225,43 @@ u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs,
225 */ 225 */
226static u32 226static u32
227vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, 227vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn,
228 struct vfp_single *vsm, u32 fpscr) 228 struct vfp_single *vsm, u32 fpscr)
229{ 229{
230 struct vfp_single *nan; 230 struct vfp_single *nan;
231 int tn, tm = 0; 231 int tn, tm = 0;
232 232
233 tn = vfp_single_type(vsn); 233 tn = vfp_single_type(vsn);
234 234
235 if (vsm) 235 if (vsm)
236 tm = vfp_single_type(vsm); 236 tm = vfp_single_type(vsm);
237 237
238 if (fpscr & FPSCR_DEFAULT_NAN) 238 if (fpscr & FPSCR_DEFAULT_NAN)
239 /* 239 /*
240 * Default NaN mode - always returns a quiet NaN 240 * Default NaN mode - always returns a quiet NaN
241 */ 241 */
242 nan = &vfp_single_default_qnan; 242 nan = &vfp_single_default_qnan;
243 else { 243 else {
244 /* 244 /*
245 * Contemporary mode - select the first signalling 245 * Contemporary mode - select the first signalling
246 * NAN, or if neither are signalling, the first 246 * NAN, or if neither are signalling, the first
247 * quiet NAN. 247 * quiet NAN.
248 */ 248 */
249 if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN)) 249 if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN))
250 nan = vsn; 250 nan = vsn;
251 else 251 else
252 nan = vsm; 252 nan = vsm;
253 /* 253 /*
254 * Make the NaN quiet. 254 * Make the NaN quiet.
255 */ 255 */
256 nan->significand |= VFP_SINGLE_SIGNIFICAND_QNAN; 256 nan->significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
257 } 257 }
258 258
259 *vsd = *nan; 259 *vsd = *nan;
260 260
261 /* 261 /*
262 * If one was a signalling NAN, raise invalid operation. 262 * If one was a signalling NAN, raise invalid operation.
263 */ 263 */
264 return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG; 264 return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG;
265} 265}
266 266
267 267
@@ -270,140 +270,140 @@ vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn,
270 */ 270 */
271static u32 vfp_single_fabs(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 271static u32 vfp_single_fabs(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
272{ 272{
273 vfp_put_float(state, vfp_single_packed_abs(m), sd); 273 vfp_put_float(state, vfp_single_packed_abs(m), sd);
274 return 0; 274 return 0;
275} 275}
276 276
277static u32 vfp_single_fcpy(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 277static u32 vfp_single_fcpy(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
278{ 278{
279 vfp_put_float(state, m, sd); 279 vfp_put_float(state, m, sd);
280 return 0; 280 return 0;
281} 281}
282 282
283static u32 vfp_single_fneg(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 283static u32 vfp_single_fneg(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
284{ 284{
285 vfp_put_float(state, vfp_single_packed_negate(m), sd); 285 vfp_put_float(state, vfp_single_packed_negate(m), sd);
286 return 0; 286 return 0;
287} 287}
288 288
289static const u16 sqrt_oddadjust[] = { 289static const u16 sqrt_oddadjust[] = {
290 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0, 290 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0,
291 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67 291 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67
292}; 292};
293 293
294static const u16 sqrt_evenadjust[] = { 294static const u16 sqrt_evenadjust[] = {
295 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e, 295 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e,
296 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002 296 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002
297}; 297};
298 298
299u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) 299u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
300{ 300{
301 int index; 301 int index;
302 u32 z, a; 302 u32 z, a;
303 303
304 if ((significand & 0xc0000000) != 0x40000000) { 304 if ((significand & 0xc0000000) != 0x40000000) {
305 pr_debug("VFP: estimate_sqrt: invalid significand\n"); 305 pr_debug("VFP: estimate_sqrt: invalid significand\n");
306 } 306 }
307 307
308 a = significand << 1; 308 a = significand << 1;
309 index = (a >> 27) & 15; 309 index = (a >> 27) & 15;
310 if (exponent & 1) { 310 if (exponent & 1) {
311 z = 0x4000 + (a >> 17) - sqrt_oddadjust[index]; 311 z = 0x4000 + (a >> 17) - sqrt_oddadjust[index];
312 z = ((a / z) << 14) + (z << 15); 312 z = ((a / z) << 14) + (z << 15);
313 a >>= 1; 313 a >>= 1;
314 } else { 314 } else {
315 z = 0x8000 + (a >> 17) - sqrt_evenadjust[index]; 315 z = 0x8000 + (a >> 17) - sqrt_evenadjust[index];
316 z = a / z + z; 316 z = a / z + z;
317 z = (z >= 0x20000) ? 0xffff8000 : (z << 15); 317 z = (z >= 0x20000) ? 0xffff8000 : (z << 15);
318 if (z <= a) 318 if (z <= a)
319 return (s32)a >> 1; 319 return (s32)a >> 1;
320 } 320 }
321 { 321 {
322 u64 v = (u64)a << 31; 322 u64 v = (u64)a << 31;
323 do_div(v, z); 323 do_div(v, z);
324 return v + (z >> 1); 324 return (u32)(v + (z >> 1));
325 } 325 }
326} 326}
327 327
328static u32 vfp_single_fsqrt(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 328static u32 vfp_single_fsqrt(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
329{ 329{
330 struct vfp_single vsm, vsd, *vsp; 330 struct vfp_single vsm, vsd, *vsp;
331 int ret, tm; 331 int ret, tm;
332 332
333 vfp_single_unpack(&vsm, m); 333 vfp_single_unpack(&vsm, m);
334 tm = vfp_single_type(&vsm); 334 tm = vfp_single_type(&vsm);
335 if (tm & (VFP_NAN|VFP_INFINITY)) { 335 if (tm & (VFP_NAN|VFP_INFINITY)) {
336 vsp = &vsd; 336 vsp = &vsd;
337 337
338 if (tm & VFP_NAN) 338 if (tm & VFP_NAN)
339 ret = vfp_propagate_nan(vsp, &vsm, NULL, fpscr); 339 ret = vfp_propagate_nan(vsp, &vsm, NULL, fpscr);
340 else if (vsm.sign == 0) { 340 else if (vsm.sign == 0) {
341 sqrt_copy: 341sqrt_copy:
342 vsp = &vsm; 342 vsp = &vsm;
343 ret = 0; 343 ret = 0;
344 } else { 344 } else {
345 sqrt_invalid: 345sqrt_invalid:
346 vsp = &vfp_single_default_qnan; 346 vsp = &vfp_single_default_qnan;
347 ret = FPSCR_IOC; 347 ret = FPSCR_IOC;
348 } 348 }
349 vfp_put_float(state, vfp_single_pack(vsp), sd); 349 vfp_put_float(state, vfp_single_pack(vsp), sd);
350 return ret; 350 return ret;
351 } 351 }
352 352
353 /* 353 /*
354 * sqrt(+/- 0) == +/- 0 354 * sqrt(+/- 0) == +/- 0
355 */ 355 */
356 if (tm & VFP_ZERO) 356 if (tm & VFP_ZERO)
357 goto sqrt_copy; 357 goto sqrt_copy;
358 358
359 /* 359 /*
360 * Normalise a denormalised number 360 * Normalise a denormalised number
361 */ 361 */
362 if (tm & VFP_DENORMAL) 362 if (tm & VFP_DENORMAL)
363 vfp_single_normalise_denormal(&vsm); 363 vfp_single_normalise_denormal(&vsm);
364 364
365 /* 365 /*
366 * sqrt(<0) = invalid 366 * sqrt(<0) = invalid
367 */ 367 */
368 if (vsm.sign) 368 if (vsm.sign)
369 goto sqrt_invalid; 369 goto sqrt_invalid;
370 370
371 vfp_single_dump("sqrt", &vsm); 371 vfp_single_dump("sqrt", &vsm);
372 372
373 /* 373 /*
374 * Estimate the square root. 374 * Estimate the square root.
375 */ 375 */
376 vsd.sign = 0; 376 vsd.sign = 0;
377 vsd.exponent = ((vsm.exponent - 127) >> 1) + 127; 377 vsd.exponent = ((vsm.exponent - 127) >> 1) + 127;
378 vsd.significand = vfp_estimate_sqrt_significand(vsm.exponent, vsm.significand) + 2; 378 vsd.significand = vfp_estimate_sqrt_significand(vsm.exponent, vsm.significand) + 2;
379 379
380 vfp_single_dump("sqrt estimate", &vsd); 380 vfp_single_dump("sqrt estimate", &vsd);
381 381
382 /* 382 /*
383 * And now adjust. 383 * And now adjust.
384 */ 384 */
385 if ((vsd.significand & VFP_SINGLE_LOW_BITS_MASK) <= 5) { 385 if ((vsd.significand & VFP_SINGLE_LOW_BITS_MASK) <= 5) {
386 if (vsd.significand < 2) { 386 if (vsd.significand < 2) {
387 vsd.significand = 0xffffffff; 387 vsd.significand = 0xffffffff;
388 } else { 388 } else {
389 u64 term; 389 u64 term;
390 s64 rem; 390 s64 rem;
391 vsm.significand <<= !(vsm.exponent & 1); 391 vsm.significand <<= !(vsm.exponent & 1);
392 term = (u64)vsd.significand * vsd.significand; 392 term = (u64)vsd.significand * vsd.significand;
393 rem = ((u64)vsm.significand << 32) - term; 393 rem = ((u64)vsm.significand << 32) - term;
394 394
395 pr_debug("VFP: term=%016llx rem=%016llx\n", term, rem); 395 pr_debug("VFP: term=%016llx rem=%016llx\n", term, rem);
396 396
397 while (rem < 0) { 397 while (rem < 0) {
398 vsd.significand -= 1; 398 vsd.significand -= 1;
399 rem += ((u64)vsd.significand << 1) | 1; 399 rem += ((u64)vsd.significand << 1) | 1;
400 } 400 }
401 vsd.significand |= rem != 0; 401 vsd.significand |= rem != 0;
402 } 402 }
403 } 403 }
404 vsd.significand = vfp_shiftright32jamming(vsd.significand, 1); 404 vsd.significand = vfp_shiftright32jamming(vsd.significand, 1);
405 405
406 return vfp_single_normaliseround(state, sd, &vsd, fpscr, 0, "fsqrt"); 406 return vfp_single_normaliseround(state, sd, &vsd, fpscr, 0, "fsqrt");
407} 407}
408 408
409/* 409/*
@@ -414,305 +414,346 @@ static u32 vfp_single_fsqrt(ARMul_State* state, int sd, int unused, s32 m, u32 f
414 */ 414 */
415static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u32 fpscr) 415static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u32 fpscr)
416{ 416{
417 s32 d; 417 s32 d;
418 u32 ret = 0; 418 u32 ret = 0;
419 419
420 d = vfp_get_float(state, sd); 420 d = vfp_get_float(state, sd);
421 if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) { 421 if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) {
422 ret |= FPSCR_C | FPSCR_V; 422 ret |= FPSCR_C | FPSCR_V;
423 if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) 423 if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1))))
424 /* 424 /*
425 * Signalling NaN, or signalling on quiet NaN 425 * Signalling NaN, or signalling on quiet NaN
426 */ 426 */
427 ret |= FPSCR_IOC; 427 ret |= FPSCR_IOC;
428 } 428 }
429 429
430 if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) { 430 if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) {
431 ret |= FPSCR_C | FPSCR_V; 431 ret |= FPSCR_C | FPSCR_V;
432 if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) 432 if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1))))
433 /* 433 /*
434 * Signalling NaN, or signalling on quiet NaN 434 * Signalling NaN, or signalling on quiet NaN
435 */ 435 */
436 ret |= FPSCR_IOC; 436 ret |= FPSCR_IOC;
437 } 437 }
438 438
439 if (ret == 0) { 439 if (ret == 0) {
440 if (d == m || vfp_single_packed_abs(d | m) == 0) { 440 if (d == m || vfp_single_packed_abs(d | m) == 0) {
441 /* 441 /*
442 * equal 442 * equal
443 */ 443 */
444 ret |= FPSCR_Z | FPSCR_C; 444 ret |= FPSCR_Z | FPSCR_C;
445 } else if (vfp_single_packed_sign(d ^ m)) { 445 } else if (vfp_single_packed_sign(d ^ m)) {
446 /* 446 /*
447 * different signs 447 * different signs
448 */ 448 */
449 if (vfp_single_packed_sign(d)) 449 if (vfp_single_packed_sign(d))
450 /* 450 /*
451 * d is negative, so d < m 451 * d is negative, so d < m
452 */ 452 */
453 ret |= FPSCR_N; 453 ret |= FPSCR_N;
454 else 454 else
455 /* 455 /*
456 * d is positive, so d > m 456 * d is positive, so d > m
457 */ 457 */
458 ret |= FPSCR_C; 458 ret |= FPSCR_C;
459 } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) { 459 } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) {
460 /* 460 /*
461 * d < m 461 * d < m
462 */ 462 */
463 ret |= FPSCR_N; 463 ret |= FPSCR_N;
464 } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) { 464 } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) {
465 /* 465 /*
466 * d > m 466 * d > m
467 */ 467 */
468 ret |= FPSCR_C; 468 ret |= FPSCR_C;
469 } 469 }
470 } 470 }
471 return ret; 471 return ret;
472} 472}
473 473
474static u32 vfp_single_fcmp(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 474static u32 vfp_single_fcmp(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
475{ 475{
476 return vfp_compare(state, sd, 0, m, fpscr); 476 return vfp_compare(state, sd, 0, m, fpscr);
477} 477}
478 478
479static u32 vfp_single_fcmpe(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 479static u32 vfp_single_fcmpe(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
480{ 480{
481 return vfp_compare(state, sd, 1, m, fpscr); 481 return vfp_compare(state, sd, 1, m, fpscr);
482} 482}
483 483
484static u32 vfp_single_fcmpz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 484static u32 vfp_single_fcmpz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
485{ 485{
486 return vfp_compare(state, sd, 0, 0, fpscr); 486 return vfp_compare(state, sd, 0, 0, fpscr);
487} 487}
488 488
489static u32 vfp_single_fcmpez(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 489static u32 vfp_single_fcmpez(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
490{ 490{
491 return vfp_compare(state, sd, 1, 0, fpscr); 491 return vfp_compare(state, sd, 1, 0, fpscr);
492}
493
494static s64 vfp_single_to_doubleintern(ARMul_State* state, s32 m, u32 fpscr) //ichfly for internal use only
495{
496 struct vfp_single vsm;
497 struct vfp_double vdd;
498 int tm;
499 u32 exceptions = 0;
500
501 vfp_single_unpack(&vsm, m);
502
503 tm = vfp_single_type(&vsm);
504
505 /*
506 * If we have a signalling NaN, signal invalid operation.
507 */
508 if (tm == VFP_SNAN)
509 exceptions = FPSCR_IOC;
510
511 if (tm & VFP_DENORMAL)
512 vfp_single_normalise_denormal(&vsm);
513
514 vdd.sign = vsm.sign;
515 vdd.significand = (u64)vsm.significand << 32;
516
517 /*
518 * If we have an infinity or NaN, the exponent must be 2047.
519 */
520 if (tm & (VFP_INFINITY | VFP_NAN)) {
521 vdd.exponent = 2047;
522 if (tm == VFP_QNAN)
523 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
524 goto pack_nan;
525 }
526 else if (tm & VFP_ZERO)
527 vdd.exponent = 0;
528 else
529 vdd.exponent = vsm.exponent + (1023 - 127);
530pack_nan:
531 vfp_double_normaliseroundintern(state, &vdd, fpscr, exceptions, "fcvtd");
532 return vfp_double_pack(&vdd);
492} 533}
493 534
494static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr) 535static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr)
495{ 536{
496 struct vfp_single vsm; 537 struct vfp_single vsm;
497 struct vfp_double vdd; 538 struct vfp_double vdd;
498 int tm; 539 int tm;
499 u32 exceptions = 0; 540 u32 exceptions = 0;
500 541
501 vfp_single_unpack(&vsm, m); 542 vfp_single_unpack(&vsm, m);
502 543
503 tm = vfp_single_type(&vsm); 544 tm = vfp_single_type(&vsm);
504 545
505 /* 546 /*
506 * If we have a signalling NaN, signal invalid operation. 547 * If we have a signalling NaN, signal invalid operation.
507 */ 548 */
508 if (tm == VFP_SNAN) 549 if (tm == VFP_SNAN)
509 exceptions = FPSCR_IOC; 550 exceptions = FPSCR_IOC;
510 551
511 if (tm & VFP_DENORMAL) 552 if (tm & VFP_DENORMAL)
512 vfp_single_normalise_denormal(&vsm); 553 vfp_single_normalise_denormal(&vsm);
513 554
514 vdd.sign = vsm.sign; 555 vdd.sign = vsm.sign;
515 vdd.significand = (u64)vsm.significand << 32; 556 vdd.significand = (u64)vsm.significand << 32;
516 557
517 /* 558 /*
518 * If we have an infinity or NaN, the exponent must be 2047. 559 * If we have an infinity or NaN, the exponent must be 2047.
519 */ 560 */
520 if (tm & (VFP_INFINITY|VFP_NAN)) { 561 if (tm & (VFP_INFINITY|VFP_NAN)) {
521 vdd.exponent = 2047; 562 vdd.exponent = 2047;
522 if (tm == VFP_QNAN) 563 if (tm == VFP_QNAN)
523 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; 564 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
524 goto pack_nan; 565 goto pack_nan;
525 } else if (tm & VFP_ZERO) 566 } else if (tm & VFP_ZERO)
526 vdd.exponent = 0; 567 vdd.exponent = 0;
527 else 568 else
528 vdd.exponent = vsm.exponent + (1023 - 127); 569 vdd.exponent = vsm.exponent + (1023 - 127);
529 570
530 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fcvtd"); 571 return vfp_double_normaliseround(state, dd, &vdd, fpscr, exceptions, "fcvtd");
531 572
532 pack_nan: 573pack_nan:
533 vfp_put_double(state, vfp_double_pack(&vdd), dd); 574 vfp_put_double(state, vfp_double_pack(&vdd), dd);
534 return exceptions; 575 return exceptions;
535} 576}
536 577
537static u32 vfp_single_fuito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 578static u32 vfp_single_fuito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
538{ 579{
539 struct vfp_single vs; 580 struct vfp_single vs;
540 581
541 vs.sign = 0; 582 vs.sign = 0;
542 vs.exponent = 127 + 31 - 1; 583 vs.exponent = 127 + 31 - 1;
543 vs.significand = (u32)m; 584 vs.significand = (u32)m;
544 585
545 return vfp_single_normaliseround(state, sd, &vs, fpscr, 0, "fuito"); 586 return vfp_single_normaliseround(state, sd, &vs, fpscr, 0, "fuito");
546} 587}
547 588
548static u32 vfp_single_fsito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 589static u32 vfp_single_fsito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
549{ 590{
550 struct vfp_single vs; 591 struct vfp_single vs;
551 592
552 vs.sign = (m & 0x80000000) >> 16; 593 vs.sign = (m & 0x80000000) >> 16;
553 vs.exponent = 127 + 31 - 1; 594 vs.exponent = 127 + 31 - 1;
554 vs.significand = vs.sign ? -m : m; 595 vs.significand = vs.sign ? -m : m;
555 596
556 return vfp_single_normaliseround(state, sd, &vs, fpscr, 0, "fsito"); 597 return vfp_single_normaliseround(state, sd, &vs, fpscr, 0, "fsito");
557} 598}
558 599
559static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 600static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
560{ 601{
561 struct vfp_single vsm; 602 struct vfp_single vsm;
562 u32 d, exceptions = 0; 603 u32 d, exceptions = 0;
563 int rmode = fpscr & FPSCR_RMODE_MASK; 604 int rmode = fpscr & FPSCR_RMODE_MASK;
564 int tm; 605 int tm;
565 606
566 vfp_single_unpack(&vsm, m); 607 vfp_single_unpack(&vsm, m);
567 vfp_single_dump("VSM", &vsm); 608 vfp_single_dump("VSM", &vsm);
568 609
569 /* 610 /*
570 * Do we have a denormalised number? 611 * Do we have a denormalised number?
571 */ 612 */
572 tm = vfp_single_type(&vsm); 613 tm = vfp_single_type(&vsm);
573 if (tm & VFP_DENORMAL) 614 if (tm & VFP_DENORMAL)
574 exceptions |= FPSCR_IDC; 615 exceptions |= FPSCR_IDC;
575 616
576 if (tm & VFP_NAN) 617 if (tm & VFP_NAN)
577 vsm.sign = 0; 618 vsm.sign = 0;
578 619
579 if (vsm.exponent >= 127 + 32) { 620 if (vsm.exponent >= 127 + 32) {
580 d = vsm.sign ? 0 : 0xffffffff; 621 d = vsm.sign ? 0 : 0xffffffff;
581 exceptions = FPSCR_IOC; 622 exceptions = FPSCR_IOC;
582 } else if (vsm.exponent >= 127 - 1) { 623 } else if (vsm.exponent >= 127 - 1) {
583 int shift = 127 + 31 - vsm.exponent; 624 int shift = 127 + 31 - vsm.exponent;
584 u32 rem, incr = 0; 625 u32 rem, incr = 0;
585 626
586 /* 627 /*
587 * 2^0 <= m < 2^32-2^8 628 * 2^0 <= m < 2^32-2^8
588 */ 629 */
589 d = (vsm.significand << 1) >> shift; 630 d = (vsm.significand << 1) >> shift;
590 rem = vsm.significand << (33 - shift); 631 rem = vsm.significand << (33 - shift);
591 632
592 if (rmode == FPSCR_ROUND_NEAREST) { 633 if (rmode == FPSCR_ROUND_NEAREST) {
593 incr = 0x80000000; 634 incr = 0x80000000;
594 if ((d & 1) == 0) 635 if ((d & 1) == 0)
595 incr -= 1; 636 incr -= 1;
596 } else if (rmode == FPSCR_ROUND_TOZERO) { 637 } else if (rmode == FPSCR_ROUND_TOZERO) {
597 incr = 0; 638 incr = 0;
598 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) { 639 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) {
599 incr = ~0; 640 incr = ~0;
600 } 641 }
601 642
602 if ((rem + incr) < rem) { 643 if ((rem + incr) < rem) {
603 if (d < 0xffffffff) 644 if (d < 0xffffffff)
604 d += 1; 645 d += 1;
605 else 646 else
606 exceptions |= FPSCR_IOC; 647 exceptions |= FPSCR_IOC;
607 } 648 }
608 649
609 if (d && vsm.sign) { 650 if (d && vsm.sign) {
610 d = 0; 651 d = 0;
611 exceptions |= FPSCR_IOC; 652 exceptions |= FPSCR_IOC;
612 } else if (rem) 653 } else if (rem)
613 exceptions |= FPSCR_IXC; 654 exceptions |= FPSCR_IXC;
614 } else { 655 } else {
615 d = 0; 656 d = 0;
616 if (vsm.exponent | vsm.significand) { 657 if (vsm.exponent | vsm.significand) {
617 exceptions |= FPSCR_IXC; 658 exceptions |= FPSCR_IXC;
618 if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) 659 if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0)
619 d = 1; 660 d = 1;
620 else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { 661 else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) {
621 d = 0; 662 d = 0;
622 exceptions |= FPSCR_IOC; 663 exceptions |= FPSCR_IOC;
623 } 664 }
624 } 665 }
625 } 666 }
626 667
627 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 668 pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
628 669
629 vfp_put_float(state, d, sd); 670 vfp_put_float(state, d, sd);
630 671
631 return exceptions; 672 return exceptions;
632} 673}
633 674
634static u32 vfp_single_ftouiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 675static u32 vfp_single_ftouiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
635{ 676{
636 return vfp_single_ftoui(state, sd, unused, m, FPSCR_ROUND_TOZERO); 677 return vfp_single_ftoui(state, sd, unused, m, FPSCR_ROUND_TOZERO);
637} 678}
638 679
639static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 680static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
640{ 681{
641 struct vfp_single vsm; 682 struct vfp_single vsm;
642 u32 d, exceptions = 0; 683 u32 d, exceptions = 0;
643 int rmode = fpscr & FPSCR_RMODE_MASK; 684 int rmode = fpscr & FPSCR_RMODE_MASK;
644 int tm; 685 int tm;
645 686
646 vfp_single_unpack(&vsm, m); 687 vfp_single_unpack(&vsm, m);
647 vfp_single_dump("VSM", &vsm); 688 vfp_single_dump("VSM", &vsm);
648 689
649 /* 690 /*
650 * Do we have a denormalised number? 691 * Do we have a denormalised number?
651 */ 692 */
652 tm = vfp_single_type(&vsm); 693 tm = vfp_single_type(&vsm);
653 if (vfp_single_type(&vsm) & VFP_DENORMAL) 694 if (vfp_single_type(&vsm) & VFP_DENORMAL)
654 exceptions |= FPSCR_IDC; 695 exceptions |= FPSCR_IDC;
655 696
656 if (tm & VFP_NAN) { 697 if (tm & VFP_NAN) {
657 d = 0; 698 d = 0;
658 exceptions |= FPSCR_IOC; 699 exceptions |= FPSCR_IOC;
659 } else if (vsm.exponent >= 127 + 32) { 700 } else if (vsm.exponent >= 127 + 32) {
660 /* 701 /*
661 * m >= 2^31-2^7: invalid 702 * m >= 2^31-2^7: invalid
662 */ 703 */
663 d = 0x7fffffff; 704 d = 0x7fffffff;
664 if (vsm.sign) 705 if (vsm.sign)
665 d = ~d; 706 d = ~d;
666 exceptions |= FPSCR_IOC; 707 exceptions |= FPSCR_IOC;
667 } else if (vsm.exponent >= 127 - 1) { 708 } else if (vsm.exponent >= 127 - 1) {
668 int shift = 127 + 31 - vsm.exponent; 709 int shift = 127 + 31 - vsm.exponent;
669 u32 rem, incr = 0; 710 u32 rem, incr = 0;
670 711
671 /* 2^0 <= m <= 2^31-2^7 */ 712 /* 2^0 <= m <= 2^31-2^7 */
672 d = (vsm.significand << 1) >> shift; 713 d = (vsm.significand << 1) >> shift;
673 rem = vsm.significand << (33 - shift); 714 rem = vsm.significand << (33 - shift);
674 715
675 if (rmode == FPSCR_ROUND_NEAREST) { 716 if (rmode == FPSCR_ROUND_NEAREST) {
676 incr = 0x80000000; 717 incr = 0x80000000;
677 if ((d & 1) == 0) 718 if ((d & 1) == 0)
678 incr -= 1; 719 incr -= 1;
679 } else if (rmode == FPSCR_ROUND_TOZERO) { 720 } else if (rmode == FPSCR_ROUND_TOZERO) {
680 incr = 0; 721 incr = 0;
681 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) { 722 } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) {
682 incr = ~0; 723 incr = ~0;
683 } 724 }
684 725
685 if ((rem + incr) < rem && d < 0xffffffff) 726 if ((rem + incr) < rem && d < 0xffffffff)
686 d += 1; 727 d += 1;
687 if (d > 0x7fffffff + (vsm.sign != 0)) { 728 if (d > (0x7fffffffu + (vsm.sign != 0))) {
688 d = 0x7fffffff + (vsm.sign != 0); 729 d = (0x7fffffffu + (vsm.sign != 0));
689 exceptions |= FPSCR_IOC; 730 exceptions |= FPSCR_IOC;
690 } else if (rem) 731 } else if (rem)
691 exceptions |= FPSCR_IXC; 732 exceptions |= FPSCR_IXC;
692 733
693 if (vsm.sign) 734 if (vsm.sign)
694 d = -d; 735 d = 0-d;
695 } else { 736 } else {
696 d = 0; 737 d = 0;
697 if (vsm.exponent | vsm.significand) { 738 if (vsm.exponent | vsm.significand) {
698 exceptions |= FPSCR_IXC; 739 exceptions |= FPSCR_IXC;
699 if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) 740 if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0)
700 d = 1; 741 d = 1;
701 else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) 742 else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign)
702 d = -1; 743 d = -1;
703 } 744 }
704 } 745 }
705 746
706 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); 747 pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
707 748
708 vfp_put_float(state, (s32)d, sd); 749 vfp_put_float(state, (s32)d, sd);
709 750
710 return exceptions; 751 return exceptions;
711} 752}
712 753
713static u32 vfp_single_ftosiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) 754static u32 vfp_single_ftosiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr)
714{ 755{
715 return vfp_single_ftosi(state, sd, unused, m, FPSCR_ROUND_TOZERO); 756 return vfp_single_ftosi(state, sd, unused, m, FPSCR_ROUND_TOZERO);
716} 757}
717 758
718static struct op fops_ext[] = { 759static struct op fops_ext[] = {
@@ -752,200 +793,237 @@ static struct op fops_ext[] = {
752 793
753static u32 794static u32
754vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn, 795vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn,
755 struct vfp_single *vsm, u32 fpscr) 796 struct vfp_single *vsm, u32 fpscr)
756{ 797{
757 struct vfp_single *vsp; 798 struct vfp_single *vsp;
758 u32 exceptions = 0; 799 u32 exceptions = 0;
759 int tn, tm; 800 int tn, tm;
760 801
761 tn = vfp_single_type(vsn); 802 tn = vfp_single_type(vsn);
762 tm = vfp_single_type(vsm); 803 tm = vfp_single_type(vsm);
763 804
764 if (tn & tm & VFP_INFINITY) { 805 if (tn & tm & VFP_INFINITY) {
765 /* 806 /*
766 * Two infinities. Are they different signs? 807 * Two infinities. Are they different signs?
767 */ 808 */
768 if (vsn->sign ^ vsm->sign) { 809 if (vsn->sign ^ vsm->sign) {
769 /* 810 /*
770 * different signs -> invalid 811 * different signs -> invalid
771 */ 812 */
772 exceptions = FPSCR_IOC; 813 exceptions = FPSCR_IOC;
773 vsp = &vfp_single_default_qnan; 814 vsp = &vfp_single_default_qnan;
774 } else { 815 } else {
775 /* 816 /*
776 * same signs -> valid 817 * same signs -> valid
777 */ 818 */
778 vsp = vsn; 819 vsp = vsn;
779 } 820 }
780 } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) { 821 } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) {
781 /* 822 /*
782 * One infinity and one number -> infinity 823 * One infinity and one number -> infinity
783 */ 824 */
784 vsp = vsn; 825 vsp = vsn;
785 } else { 826 } else {
786 /* 827 /*
787 * 'n' is a NaN of some type 828 * 'n' is a NaN of some type
788 */ 829 */
789 return vfp_propagate_nan(vsd, vsn, vsm, fpscr); 830 return vfp_propagate_nan(vsd, vsn, vsm, fpscr);
790 } 831 }
791 *vsd = *vsp; 832 *vsd = *vsp;
792 return exceptions; 833 return exceptions;
793} 834}
794 835
795static u32 836static u32
796vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, 837vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn,
797 struct vfp_single *vsm, u32 fpscr) 838 struct vfp_single *vsm, u32 fpscr)
798{ 839{
799 u32 exp_diff, m_sig; 840 u32 exp_diff, m_sig;
800 841
801 if (vsn->significand & 0x80000000 || 842 if (vsn->significand & 0x80000000 ||
802 vsm->significand & 0x80000000) { 843 vsm->significand & 0x80000000) {
803 pr_info("VFP: bad FP values\n"); 844 pr_info("VFP: bad FP values in %s\n", __func__);
804 vfp_single_dump("VSN", vsn); 845 vfp_single_dump("VSN", vsn);
805 vfp_single_dump("VSM", vsm); 846 vfp_single_dump("VSM", vsm);
806 } 847 }
807 848
808 /* 849 /*
809 * Ensure that 'n' is the largest magnitude number. Note that 850 * Ensure that 'n' is the largest magnitude number. Note that
810 * if 'n' and 'm' have equal exponents, we do not swap them. 851 * if 'n' and 'm' have equal exponents, we do not swap them.
811 * This ensures that NaN propagation works correctly. 852 * This ensures that NaN propagation works correctly.
812 */ 853 */
813 if (vsn->exponent < vsm->exponent) { 854 if (vsn->exponent < vsm->exponent) {
814 struct vfp_single *t = vsn; 855 struct vfp_single *t = vsn;
815 vsn = vsm; 856 vsn = vsm;
816 vsm = t; 857 vsm = t;
817 } 858 }
818 859
819 /* 860 /*
820 * Is 'n' an infinity or a NaN? Note that 'm' may be a number, 861 * Is 'n' an infinity or a NaN? Note that 'm' may be a number,
821 * infinity or a NaN here. 862 * infinity or a NaN here.
822 */ 863 */
823 if (vsn->exponent == 255) 864 if (vsn->exponent == 255)
824 return vfp_single_fadd_nonnumber(vsd, vsn, vsm, fpscr); 865 return vfp_single_fadd_nonnumber(vsd, vsn, vsm, fpscr);
825 866
826 /* 867 /*
827 * We have two proper numbers, where 'vsn' is the larger magnitude. 868 * We have two proper numbers, where 'vsn' is the larger magnitude.
828 * 869 *
829 * Copy 'n' to 'd' before doing the arithmetic. 870 * Copy 'n' to 'd' before doing the arithmetic.
830 */ 871 */
831 *vsd = *vsn; 872 *vsd = *vsn;
832 873
833 /* 874 /*
834 * Align both numbers. 875 * Align both numbers.
835 */ 876 */
836 exp_diff = vsn->exponent - vsm->exponent; 877 exp_diff = vsn->exponent - vsm->exponent;
837 m_sig = vfp_shiftright32jamming(vsm->significand, exp_diff); 878 m_sig = vfp_shiftright32jamming(vsm->significand, exp_diff);
838 879
839 /* 880 /*
840 * If the signs are different, we are really subtracting. 881 * If the signs are different, we are really subtracting.
841 */ 882 */
842 if (vsn->sign ^ vsm->sign) { 883 if (vsn->sign ^ vsm->sign) {
843 m_sig = vsn->significand - m_sig; 884 m_sig = vsn->significand - m_sig;
844 if ((s32)m_sig < 0) { 885 if ((s32)m_sig < 0) {
845 vsd->sign = vfp_sign_negate(vsd->sign); 886 vsd->sign = vfp_sign_negate(vsd->sign);
846 m_sig = -m_sig; 887 m_sig = 0-m_sig;
847 } else if (m_sig == 0) { 888 } else if (m_sig == 0) {
848 vsd->sign = (fpscr & FPSCR_RMODE_MASK) == 889 vsd->sign = (fpscr & FPSCR_RMODE_MASK) ==
849 FPSCR_ROUND_MINUSINF ? 0x8000 : 0; 890 FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
850 } 891 }
851 } else { 892 } else {
852 m_sig = vsn->significand + m_sig; 893 m_sig = vsn->significand + m_sig;
853 } 894 }
854 vsd->significand = m_sig; 895 vsd->significand = m_sig;
855 896
856 return 0; 897 return 0;
857} 898}
858 899
859static u32 900static u32
860vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_single *vsm, u32 fpscr) 901vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_single *vsm, u32 fpscr)
861{ 902{
862 vfp_single_dump("VSN", vsn); 903 vfp_single_dump("VSN", vsn);
863 vfp_single_dump("VSM", vsm); 904 vfp_single_dump("VSM", vsm);
864 905
865 /* 906 /*
866 * Ensure that 'n' is the largest magnitude number. Note that 907 * Ensure that 'n' is the largest magnitude number. Note that
867 * if 'n' and 'm' have equal exponents, we do not swap them. 908 * if 'n' and 'm' have equal exponents, we do not swap them.
868 * This ensures that NaN propagation works correctly. 909 * This ensures that NaN propagation works correctly.
869 */ 910 */
870 if (vsn->exponent < vsm->exponent) { 911 if (vsn->exponent < vsm->exponent) {
871 struct vfp_single *t = vsn; 912 struct vfp_single *t = vsn;
872 vsn = vsm; 913 vsn = vsm;
873 vsm = t; 914 vsm = t;
874 pr_debug("VFP: swapping M <-> N\n"); 915 pr_debug("VFP: swapping M <-> N\n");
875 } 916 }
876 917
877 vsd->sign = vsn->sign ^ vsm->sign; 918 vsd->sign = vsn->sign ^ vsm->sign;
878 919
879 /* 920 /*
880 * If 'n' is an infinity or NaN, handle it. 'm' may be anything. 921 * If 'n' is an infinity or NaN, handle it. 'm' may be anything.
881 */ 922 */
882 if (vsn->exponent == 255) { 923 if (vsn->exponent == 255) {
883 if (vsn->significand || (vsm->exponent == 255 && vsm->significand)) 924 if (vsn->significand || (vsm->exponent == 255 && vsm->significand))
884 return vfp_propagate_nan(vsd, vsn, vsm, fpscr); 925 return vfp_propagate_nan(vsd, vsn, vsm, fpscr);
885 if ((vsm->exponent | vsm->significand) == 0) { 926 if ((vsm->exponent | vsm->significand) == 0) {
886 *vsd = vfp_single_default_qnan; 927 *vsd = vfp_single_default_qnan;
887 return FPSCR_IOC; 928 return FPSCR_IOC;
888 } 929 }
889 vsd->exponent = vsn->exponent; 930 vsd->exponent = vsn->exponent;
890 vsd->significand = 0; 931 vsd->significand = 0;
891 return 0; 932 return 0;
892 } 933 }
893 934
894 /* 935 /*
895 * If 'm' is zero, the result is always zero. In this case, 936 * If 'm' is zero, the result is always zero. In this case,
896 * 'n' may be zero or a number, but it doesn't matter which. 937 * 'n' may be zero or a number, but it doesn't matter which.
897 */ 938 */
898 if ((vsm->exponent | vsm->significand) == 0) { 939 if ((vsm->exponent | vsm->significand) == 0) {
899 vsd->exponent = 0; 940 vsd->exponent = 0;
900 vsd->significand = 0; 941 vsd->significand = 0;
901 return 0; 942 return 0;
902 } 943 }
903 944
904 /* 945 /*
905 * We add 2 to the destination exponent for the same reason as 946 * We add 2 to the destination exponent for the same reason as
906 * the addition case - though this time we have +1 from each 947 * the addition case - though this time we have +1 from each
907 * input operand. 948 * input operand.
908 */ 949 */
909 vsd->exponent = vsn->exponent + vsm->exponent - 127 + 2; 950 vsd->exponent = vsn->exponent + vsm->exponent - 127 + 2;
910 vsd->significand = vfp_hi64to32jamming((u64)vsn->significand * vsm->significand); 951 vsd->significand = vfp_hi64to32jamming((u64)vsn->significand * vsm->significand);
911 952
912 vfp_single_dump("VSD", vsd); 953 vfp_single_dump("VSD", vsd);
913 return 0; 954 return 0;
914} 955}
915 956
916#define NEG_MULTIPLY (1 << 0) 957#define NEG_MULTIPLY (1 << 0)
917#define NEG_SUBTRACT (1 << 1) 958#define NEG_SUBTRACT (1 << 1)
918 959
919static u32 960static u32
920vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr, u32 negate, const char *func) 961vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr, u32 negate, char *func)
921{ 962{
922 struct vfp_single vsd, vsp, vsn, vsm; 963
923 u32 exceptions; 964 {
924 s32 v; 965 struct vfp_single vsd, vsp, vsn, vsm;
966 u32 exceptions;
967 s32 v;
968
969
970
971 v = vfp_get_float(state, sn);
972 pr_debug("VFP: s%u = %08x\n", sn, v);
973 vfp_single_unpack(&vsn, v);
974 if (vsn.exponent == 0 && vsn.significand)
975 vfp_single_normalise_denormal(&vsn);
976
977 vfp_single_unpack(&vsm, m);
978 if (vsm.exponent == 0 && vsm.significand)
979 vfp_single_normalise_denormal(&vsm);
980
981 exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr);
982
983 if (negate & NEG_MULTIPLY)
984 vsp.sign = vfp_sign_negate(vsp.sign);
985
986 v = vfp_get_float(state, sd);
987 pr_debug("VFP: s%u = %08x\n", sd, v);
988 vfp_single_unpack(&vsn, v);
989 if (negate & NEG_SUBTRACT)
990 vsn.sign = vfp_sign_negate(vsn.sign);
991
992 exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr);
993
994 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, func);
995 }
996
997 struct vfp_double vsd, vsp, vsn, vsm;
998 u32 exceptions;
999 s32 v;
1000 s64 vd;
1001 s64 md;
1002
1003 v = vfp_get_float(state, sn);
1004 vd = vfp_single_to_doubleintern(state, v, fpscr);
1005 vfp_double_unpack(&vsn, vd);
1006
1007 md = vfp_single_to_doubleintern(state, m, fpscr);
1008 vfp_double_unpack(&vsm, md);
1009
1010 exceptions = vfp_double_multiply(&vsp, &vsn, &vsm, fpscr);
1011 if (negate & NEG_MULTIPLY)
1012 vsp.sign = vfp_sign_negate(vsp.sign);
925 1013
926 v = vfp_get_float(state, sn); 1014 v = vfp_get_float(state, sd);
927 pr_debug("VFP: s%u = %08x\n", sn, v); 1015 vd = vfp_single_to_doubleintern(state, v, fpscr);
928 vfp_single_unpack(&vsn, v); 1016 vfp_double_unpack(&vsn, vd);
929 if (vsn.exponent == 0 && vsn.significand)
930 vfp_single_normalise_denormal(&vsn);
931 1017
932 vfp_single_unpack(&vsm, m); 1018 if (negate & NEG_SUBTRACT)
933 if (vsm.exponent == 0 && vsm.significand) 1019 vsn.sign = vfp_sign_negate(vsn.sign);
934 vfp_single_normalise_denormal(&vsm);
935 1020
936 exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr); 1021 exceptions |= vfp_double_add(&vsd, &vsn, &vsp, fpscr);
937 if (negate & NEG_MULTIPLY)
938 vsp.sign = vfp_sign_negate(vsp.sign);
939 1022
940 v = vfp_get_float(state, sd); 1023 s64 debug = vfp_double_pack(&vsd);
941 pr_debug("VFP: s%u = %08x\n", sd, v);
942 vfp_single_unpack(&vsn, v);
943 if (negate & NEG_SUBTRACT)
944 vsn.sign = vfp_sign_negate(vsn.sign);
945 1024
946 exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr); 1025 return vfp_double_fcvtsinterncutting(state, sd, &vsd, fpscr);
947 1026
948 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, func);
949} 1027}
950 1028
951/* 1029/*
@@ -957,8 +1035,8 @@ vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fp
957 */ 1035 */
958static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1036static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
959{ 1037{
960 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd); 1038 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd);
961 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, 0, "fmac"); 1039 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, 0, "fmac");
962} 1040}
963 1041
964/* 1042/*
@@ -966,8 +1044,8 @@ static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
966 */ 1044 */
967static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1045static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
968{ 1046{
969 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sd, sn); 1047 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sd, sn);
970 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac"); 1048 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac");
971} 1049}
972 1050
973/* 1051/*
@@ -975,8 +1053,8 @@ static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr
975 */ 1053 */
976static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1054static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
977{ 1055{
978 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd); 1056 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd);
979 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc"); 1057 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc");
980} 1058}
981 1059
982/* 1060/*
@@ -984,8 +1062,8 @@ static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
984 */ 1062 */
985static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1063static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
986{ 1064{
987 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd); 1065 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd);
988 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); 1066 return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc");
989} 1067}
990 1068
991/* 1069/*
@@ -993,22 +1071,22 @@ static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr
993 */ 1071 */
994static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1072static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
995{ 1073{
996 struct vfp_single vsd, vsn, vsm; 1074 struct vfp_single vsd, vsn, vsm;
997 u32 exceptions; 1075 u32 exceptions;
998 s32 n = vfp_get_float(state, sn); 1076 s32 n = vfp_get_float(state, sn);
999 1077
1000 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, n); 1078 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, n);
1001 1079
1002 vfp_single_unpack(&vsn, n); 1080 vfp_single_unpack(&vsn, n);
1003 if (vsn.exponent == 0 && vsn.significand) 1081 if (vsn.exponent == 0 && vsn.significand)
1004 vfp_single_normalise_denormal(&vsn); 1082 vfp_single_normalise_denormal(&vsn);
1005 1083
1006 vfp_single_unpack(&vsm, m); 1084 vfp_single_unpack(&vsm, m);
1007 if (vsm.exponent == 0 && vsm.significand) 1085 if (vsm.exponent == 0 && vsm.significand)
1008 vfp_single_normalise_denormal(&vsm); 1086 vfp_single_normalise_denormal(&vsm);
1009 1087
1010 exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr); 1088 exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr);
1011 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fmul"); 1089 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fmul");
1012} 1090}
1013 1091
1014/* 1092/*
@@ -1016,23 +1094,23 @@ static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1016 */ 1094 */
1017static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1095static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1018{ 1096{
1019 struct vfp_single vsd, vsn, vsm; 1097 struct vfp_single vsd, vsn, vsm;
1020 u32 exceptions; 1098 u32 exceptions;
1021 s32 n = vfp_get_float(state, sn); 1099 s32 n = vfp_get_float(state, sn);
1022 1100
1023 pr_debug("VFP: s%u = %08x\n", sn, n); 1101 pr_debug("VFP: s%u = %08x\n", sn, n);
1024 1102
1025 vfp_single_unpack(&vsn, n); 1103 vfp_single_unpack(&vsn, n);
1026 if (vsn.exponent == 0 && vsn.significand) 1104 if (vsn.exponent == 0 && vsn.significand)
1027 vfp_single_normalise_denormal(&vsn); 1105 vfp_single_normalise_denormal(&vsn);
1028 1106
1029 vfp_single_unpack(&vsm, m); 1107 vfp_single_unpack(&vsm, m);
1030 if (vsm.exponent == 0 && vsm.significand) 1108 if (vsm.exponent == 0 && vsm.significand)
1031 vfp_single_normalise_denormal(&vsm); 1109 vfp_single_normalise_denormal(&vsm);
1032 1110
1033 exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr); 1111 exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr);
1034 vsd.sign = vfp_sign_negate(vsd.sign); 1112 vsd.sign = vfp_sign_negate(vsd.sign);
1035 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fnmul"); 1113 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fnmul");
1036} 1114}
1037 1115
1038/* 1116/*
@@ -1040,26 +1118,26 @@ static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr
1040 */ 1118 */
1041static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1119static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1042{ 1120{
1043 struct vfp_single vsd, vsn, vsm; 1121 struct vfp_single vsd, vsn, vsm;
1044 u32 exceptions; 1122 u32 exceptions;
1045 s32 n = vfp_get_float(state, sn); 1123 s32 n = vfp_get_float(state, sn);
1046 1124
1047 pr_debug("VFP: s%u = %08x\n", sn, n); 1125 pr_debug("VFP: s%u = %08x\n", sn, n);
1048 1126
1049 /* 1127 /*
1050 * Unpack and normalise denormals. 1128 * Unpack and normalise denormals.
1051 */ 1129 */
1052 vfp_single_unpack(&vsn, n); 1130 vfp_single_unpack(&vsn, n);
1053 if (vsn.exponent == 0 && vsn.significand) 1131 if (vsn.exponent == 0 && vsn.significand)
1054 vfp_single_normalise_denormal(&vsn); 1132 vfp_single_normalise_denormal(&vsn);
1055 1133
1056 vfp_single_unpack(&vsm, m); 1134 vfp_single_unpack(&vsm, m);
1057 if (vsm.exponent == 0 && vsm.significand) 1135 if (vsm.exponent == 0 && vsm.significand)
1058 vfp_single_normalise_denormal(&vsm); 1136 vfp_single_normalise_denormal(&vsm);
1059 1137
1060 exceptions = vfp_single_add(&vsd, &vsn, &vsm, fpscr); 1138 exceptions = vfp_single_add(&vsd, &vsn, &vsm, fpscr);
1061 1139
1062 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fadd"); 1140 return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fadd");
1063} 1141}
1064 1142
1065/* 1143/*
@@ -1067,11 +1145,11 @@ static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1067 */ 1145 */
1068static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1146static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1069{ 1147{
1070 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd); 1148 pr_debug("In %sVFP: s%u = %08x\n", __FUNCTION__, sn, sd);
1071 /* 1149 /*
1072 * Subtraction is addition with one sign inverted. 1150 * Subtraction is addition with one sign inverted.
1073 */ 1151 */
1074 return vfp_single_fadd(state, sd, sn, vfp_single_packed_negate(m), fpscr); 1152 return vfp_single_fadd(state, sd, sn, vfp_single_packed_negate(m), fpscr);
1075} 1153}
1076 1154
1077/* 1155/*
@@ -1079,107 +1157,107 @@ static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1079 */ 1157 */
1080static u32 vfp_single_fdiv(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) 1158static u32 vfp_single_fdiv(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr)
1081{ 1159{
1082 struct vfp_single vsd, vsn, vsm; 1160 struct vfp_single vsd, vsn, vsm;
1083 u32 exceptions = 0; 1161 u32 exceptions = 0;
1084 s32 n = vfp_get_float(state, sn); 1162 s32 n = vfp_get_float(state, sn);
1085 int tm, tn; 1163 int tm, tn;
1086 1164
1087 pr_debug("VFP: s%u = %08x\n", sn, n); 1165 pr_debug("VFP: s%u = %08x\n", sn, n);
1088 1166
1089 vfp_single_unpack(&vsn, n); 1167 vfp_single_unpack(&vsn, n);
1090 vfp_single_unpack(&vsm, m); 1168 vfp_single_unpack(&vsm, m);
1091 1169
1092 vsd.sign = vsn.sign ^ vsm.sign; 1170 vsd.sign = vsn.sign ^ vsm.sign;
1093 1171
1094 tn = vfp_single_type(&vsn); 1172 tn = vfp_single_type(&vsn);
1095 tm = vfp_single_type(&vsm); 1173 tm = vfp_single_type(&vsm);
1096 1174
1097 /* 1175 /*
1098 * Is n a NAN? 1176 * Is n a NAN?
1099 */ 1177 */
1100 if (tn & VFP_NAN) 1178 if (tn & VFP_NAN)
1101 goto vsn_nan; 1179 goto vsn_nan;
1102 1180
1103 /* 1181 /*
1104 * Is m a NAN? 1182 * Is m a NAN?
1105 */ 1183 */
1106 if (tm & VFP_NAN) 1184 if (tm & VFP_NAN)
1107 goto vsm_nan; 1185 goto vsm_nan;
1108 1186
1109 /* 1187 /*
1110 * If n and m are infinity, the result is invalid 1188 * If n and m are infinity, the result is invalid
1111 * If n and m are zero, the result is invalid 1189 * If n and m are zero, the result is invalid
1112 */ 1190 */
1113 if (tm & tn & (VFP_INFINITY|VFP_ZERO)) 1191 if (tm & tn & (VFP_INFINITY|VFP_ZERO))
1114 goto invalid; 1192 goto invalid;
1115 1193
1116 /* 1194 /*
1117 * If n is infinity, the result is infinity 1195 * If n is infinity, the result is infinity
1118 */ 1196 */
1119 if (tn & VFP_INFINITY) 1197 if (tn & VFP_INFINITY)
1120 goto infinity; 1198 goto infinity;
1121 1199
1122 /* 1200 /*
1123 * If m is zero, raise div0 exception 1201 * If m is zero, raise div0 exception
1124 */ 1202 */
1125 if (tm & VFP_ZERO) 1203 if (tm & VFP_ZERO)
1126 goto divzero; 1204 goto divzero;
1127 1205
1128 /* 1206 /*
1129 * If m is infinity, or n is zero, the result is zero 1207 * If m is infinity, or n is zero, the result is zero
1130 */ 1208 */
1131 if (tm & VFP_INFINITY || tn & VFP_ZERO) 1209 if (tm & VFP_INFINITY || tn & VFP_ZERO)
1132 goto zero; 1210 goto zero;
1133 1211
1134 if (tn & VFP_DENORMAL) 1212 if (tn & VFP_DENORMAL)
1135 vfp_single_normalise_denormal(&vsn); 1213 vfp_single_normalise_denormal(&vsn);
1136 if (tm & VFP_DENORMAL) 1214 if (tm & VFP_DENORMAL)
1137 vfp_single_normalise_denormal(&vsm); 1215 vfp_single_normalise_denormal(&vsm);
1138 1216
1139 /* 1217 /*
1140 * Ok, we have two numbers, we can perform division. 1218 * Ok, we have two numbers, we can perform division.
1141 */ 1219 */
1142 vsd.exponent = vsn.exponent - vsm.exponent + 127 - 1; 1220 vsd.exponent = vsn.exponent - vsm.exponent + 127 - 1;
1143 vsm.significand <<= 1; 1221 vsm.significand <<= 1;
1144 if (vsm.significand <= (2 * vsn.significand)) { 1222 if (vsm.significand <= (2 * vsn.significand)) {
1145 vsn.significand >>= 1; 1223 vsn.significand >>= 1;
1146 vsd.exponent++; 1224 vsd.exponent++;
1147 } 1225 }
1148 { 1226 {
1149 u64 significand = (u64)vsn.significand << 32; 1227 u64 significand = (u64)vsn.significand << 32;
1150 do_div(significand, vsm.significand); 1228 do_div(significand, vsm.significand);
1151 vsd.significand = significand; 1229 vsd.significand = (u32)significand;
1152 } 1230 }
1153 if ((vsd.significand & 0x3f) == 0) 1231 if ((vsd.significand & 0x3f) == 0)
1154 vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); 1232 vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
1155 1233
1156 return vfp_single_normaliseround(state, sd, &vsd, fpscr, 0, "fdiv"); 1234 return vfp_single_normaliseround(state, sd, &vsd, fpscr, 0, "fdiv");
1157 1235
1158 vsn_nan: 1236vsn_nan:
1159 exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr); 1237 exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr);
1160 pack: 1238pack:
1161 vfp_put_float(state, vfp_single_pack(&vsd), sd); 1239 vfp_put_float(state, vfp_single_pack(&vsd), sd);
1162 return exceptions; 1240 return exceptions;
1163 1241
1164 vsm_nan: 1242vsm_nan:
1165 exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr); 1243 exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr);
1166 goto pack; 1244 goto pack;
1167 1245
1168 zero: 1246zero:
1169 vsd.exponent = 0; 1247 vsd.exponent = 0;
1170 vsd.significand = 0; 1248 vsd.significand = 0;
1171 goto pack; 1249 goto pack;
1172 1250
1173 divzero: 1251divzero:
1174 exceptions = FPSCR_DZC; 1252 exceptions = FPSCR_DZC;
1175 infinity: 1253infinity:
1176 vsd.exponent = 255; 1254 vsd.exponent = 255;
1177 vsd.significand = 0; 1255 vsd.significand = 0;
1178 goto pack; 1256 goto pack;
1179 1257
1180 invalid: 1258invalid:
1181 vfp_put_float(state, vfp_single_pack(&vfp_single_default_qnan), sd); 1259 vfp_put_float(state, vfp_single_pack(&vfp_single_default_qnan), sd);
1182 return FPSCR_IOC; 1260 return FPSCR_IOC;
1183} 1261}
1184 1262
1185static struct op fops[] = { 1263static struct op fops[] = {
@@ -1199,80 +1277,80 @@ static struct op fops[] = {
1199 1277
1200u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) 1278u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr)
1201{ 1279{
1202 u32 op = inst & FOP_MASK; 1280 u32 op = inst & FOP_MASK;
1203 u32 exceptions = 0; 1281 u32 exceptions = 0;
1204 unsigned int dest; 1282 unsigned int dest;
1205 unsigned int sn = vfp_get_sn(inst); 1283 unsigned int sn = vfp_get_sn(inst);
1206 unsigned int sm = vfp_get_sm(inst); 1284 unsigned int sm = vfp_get_sm(inst);
1207 unsigned int vecitr, veclen, vecstride; 1285 unsigned int vecitr, veclen, vecstride;
1208 struct op *fop; 1286 struct op *fop;
1209 pr_debug("In %s\n", __FUNCTION__); 1287 pr_debug("In %s\n", __FUNCTION__);
1210 1288
1211 vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); 1289 vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
1212 1290
1213 fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; 1291 fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
1214 1292
1215 /* 1293 /*
1216 * fcvtsd takes a dN register number as destination, not sN. 1294 * fcvtsd takes a dN register number as destination, not sN.
1217 * Technically, if bit 0 of dd is set, this is an invalid 1295 * Technically, if bit 0 of dd is set, this is an invalid
1218 * instruction. However, we ignore this for efficiency. 1296 * instruction. However, we ignore this for efficiency.
1219 * It also only operates on scalars. 1297 * It also only operates on scalars.
1220 */ 1298 */
1221 if (fop->flags & OP_DD) 1299 if (fop->flags & OP_DD)
1222 dest = vfp_get_dd(inst); 1300 dest = vfp_get_dd(inst);
1223 else 1301 else
1224 dest = vfp_get_sd(inst); 1302 dest = vfp_get_sd(inst);
1225 1303
1226 /* 1304 /*
1227 * If destination bank is zero, vector length is always '1'. 1305 * If destination bank is zero, vector length is always '1'.
1228 * ARM DDI0100F C5.1.3, C5.3.2. 1306 * ARM DDI0100F C5.1.3, C5.3.2.
1229 */ 1307 */
1230 if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0) 1308 if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0)
1231 veclen = 0; 1309 veclen = 0;
1232 else 1310 else
1233 veclen = fpscr & FPSCR_LENGTH_MASK; 1311 veclen = fpscr & FPSCR_LENGTH_MASK;
1234 1312
1235 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1313 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
1236 (veclen >> FPSCR_LENGTH_BIT) + 1); 1314 (veclen >> FPSCR_LENGTH_BIT) + 1);
1237 1315
1238 if (!fop->fn) { 1316 if (!fop->fn) {
1239 printf("VFP: could not find single op %d, inst=0x%x@0x%x\n", FEXT_TO_IDX(inst), inst, state->Reg[15]); 1317 printf("VFP: could not find single op %d, inst=0x%x@0x%x\n", FEXT_TO_IDX(inst), inst, state->Reg[15]);
1240 exit(-1); 1318 exit(-1);
1241 goto invalid; 1319 goto invalid;
1242 } 1320 }
1243 1321
1244 for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { 1322 for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
1245 s32 m = vfp_get_float(state, sm); 1323 s32 m = vfp_get_float(state, sm);
1246 u32 except; 1324 u32 except;
1247 char type; 1325 char type;
1248 1326
1249 type = fop->flags & OP_DD ? 'd' : 's'; 1327 type = fop->flags & OP_DD ? 'd' : 's';
1250 if (op == FOP_EXT) 1328 if (op == FOP_EXT)
1251 pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n", 1329 pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n",
1252 vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, 1330 vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
1253 sm, m); 1331 sm, m);
1254 else 1332 else
1255 pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n", 1333 pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n",
1256 vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, 1334 vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
1257 FOP_TO_IDX(op), sm, m); 1335 FOP_TO_IDX(op), sm, m);
1258 1336
1259 except = fop->fn(state, dest, sn, m, fpscr); 1337 except = fop->fn(state, dest, sn, m, fpscr);
1260 pr_debug("VFP: itr%d: exceptions=%08x\n", 1338 pr_debug("VFP: itr%d: exceptions=%08x\n",
1261 vecitr >> FPSCR_LENGTH_BIT, except); 1339 vecitr >> FPSCR_LENGTH_BIT, except);
1262 1340
1263 exceptions |= except; 1341 exceptions |= except;
1264 1342
1265 /* 1343 /*
1266 * CHECK: It appears to be undefined whether we stop when 1344 * CHECK: It appears to be undefined whether we stop when
1267 * we encounter an exception. We continue. 1345 * we encounter an exception. We continue.
1268 */ 1346 */
1269 dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7); 1347 dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
1270 sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); 1348 sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
1271 if (FREG_BANK(sm) != 0) 1349 if (FREG_BANK(sm) != 0)
1272 sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7); 1350 sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);
1273 } 1351 }
1274 return exceptions; 1352 return exceptions;
1275 1353
1276 invalid: 1354invalid:
1277 return (u32)-1; 1355 return (u32)-1;
1278} 1356}
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index eb2c73f93..6c02a43d9 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -57,6 +57,8 @@ const Interface::FunctionInfo FunctionTable[] = {
57 {0x00030100, nullptr, "RegisterService"}, 57 {0x00030100, nullptr, "RegisterService"},
58 {0x000400C0, nullptr, "UnregisterService"}, 58 {0x000400C0, nullptr, "UnregisterService"},
59 {0x00050100, GetServiceHandle, "GetServiceHandle"}, 59 {0x00050100, GetServiceHandle, "GetServiceHandle"},
60 {0x000B0000, nullptr, "ReceiveNotification"},
61 {0x000C0080, nullptr, "PublishToSubscriber"}
60}; 62};
61 63
62//////////////////////////////////////////////////////////////////////////////////////////////////// 64////////////////////////////////////////////////////////////////////////////////////////////////////