cpu_arith.h

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00082 /* comparison */
00083 #define DO_CMPEQ  RCV = (RAV == RBV) ? 1 : 0;
00084 #define DO_CMPLT  RCV = ((s64) RAV < (s64) RBV) ? 1 : 0;
00085 #define DO_CMPLE  RCV = ((s64) RAV <= (s64) RBV) ? 1 : 0;
00086 
00087 /* addition */
00088 #define DO_ADDQ   RCV = RAV + RBV;
00089 #define DO_S4ADDQ RCV = (RAV * 4) + RBV;
00090 #define DO_S8ADDQ RCV = (RAV * 8) + RBV;
00091 
00092 #define DO_ADDQ_V                                                               \
00093   {                                                                             \
00094     u64 rav = RAV;                                                              \
00095     u64 rbv = RBV;                                                              \
00096     RCV = rav + rbv;                                                            \
00097                                                                              \
00098     /* test for integer overflow */                                             \
00099     if(((~rav ^ rbv) & (rav ^ RCV)) & Q_SIGN)                                   \
00100     {                                                                           \
00101       ARITH_TRAP_I(TRAP_IOV, RC);                                               \
00102       printf("ADDQ_V %016"LL "x + %016"LL "x = %016"LL "x + TRAP.\n", rav, rbv, \
00103              RCV);                                                              \
00104     }                                                                           \
00105   }
00106 
00107 #define DO_ADDL   RCV = sext_u64_32(RAV + RBV);
00108 #define DO_S4ADDL RCV = sext_u64_32((RAV * 4) + RBV);
00109 #define DO_S8ADDL RCV = sext_u64_32((RAV * 8) + RBV);
00110 
00111 #define DO_ADDL_V                                                               \
00112   {                                                                             \
00113     u64 rav = RAV;                                                              \
00114     u64 rbv = RBV;                                                              \
00115     RCV = sext_u64_32(rav + rbv);                                               \
00116                                                                              \
00117     /* test for integer overflow */                                             \
00118     if(((~rav ^ rbv) & (rav ^ RCV)) & L_SIGN)                                   \
00119     {                                                                           \
00120       ARITH_TRAP_I(TRAP_IOV, RC);                                               \
00121       printf("ADDL_V %016"LL "x + %016"LL "x = %016"LL "x + TRAP.\n", rav, rbv, \
00122              RCV);                                                              \
00123     }                                                                           \
00124   }
00125 
00126 #define DO_CTLZ   temp_64 = 0; \
00127   temp_64_2 = RBV;             \
00128   for(i = 63; i >= 0; i--)     \
00129     if((temp_64_2 >> i) & 1)   \
00130       break;                   \
00131     else                       \
00132       temp_64++;               \
00133   RCV = temp_64;
00134 
00135 #define DO_CTPOP  temp_64 = 0; \
00136   temp_64_2 = RBV;             \
00137   for(i = 0; i < 64; i++)      \
00138     if((temp_64_2 >> i) & 1)   \
00139       temp_64++;               \
00140   RCV = temp_64;
00141 
00142 #define DO_CTTZ   temp_64 = 0; \
00143   temp_64_2 = RBV;             \
00144   for(i = 0; i < 64; i++)      \
00145     if((temp_64_2 >> i) & 1)   \
00146       break;                   \
00147     else                       \
00148       temp_64++;               \
00149   RCV = temp_64;
00150 
00151 #define DO_CMPULT RCV = ((u64) RAV < (u64) RBV) ? 1 : 0;
00152 #define DO_CMPULE RCV = ((u64) RAV <= (u64) RBV) ? 1 : 0;
00153 
00154 /* multiplication */
00155 #define DO_MULL RCV = sext_u64_32(sext_u64_32(RAV) * sext_u64_32(RBV));
00156 
00157 #define DO_MULL_V                                                               \
00158   {                                                                             \
00159     u64 rav = RAV;                                                              \
00160     u64 rbv = RBV;                                                              \
00161     u64 sr = sext_u64_32(rav) * sext_u64_32(rbv);                               \
00162     RCV = sext_u64_32(sr);                                                      \
00163     if((RCV ^ sr) & U64(0xffffffff00000000))                                    \
00164     {                                                                           \
00165       ARITH_TRAP_I(TRAP_IOV, RC);                                               \
00166       printf("MULL_V %016"LL "x * %016"LL "x = %016"LL "x + TRAP.\n", rav, rbv, \
00167              RCV);                                                              \
00168     }                                                                           \
00169   }
00170 
00171 #define DO_MULQ RCV = RAV * RBV;
00172 
00173 #define DO_MULQ_V                                                               \
00174   {                                                                             \
00175     u64 rav = RAV;                                                              \
00176     u64 rbv = RBV;                                                              \
00177     u64 t64;                                                                    \
00178     RCV = uemul64(rav, rbv, &t64);                                              \
00179     if(Q_GETSIGN(rav))                                                          \
00180       t64 -= rbv;                                                               \
00181     if(Q_GETSIGN(rbv))                                                          \
00182       t64 -= rav;                                                               \
00183     if(Q_GETSIGN(RCV) ? (t64 != X64_QUAD) : (t64 != 0))                         \
00184     {                                                                           \
00185       ARITH_TRAP_I(TRAP_IOV, RC);                                               \
00186       printf("MULQ_V %016"LL "x * %016"LL "x = %016"LL "x + TRAP.\n", rav, rbv, \
00187              RCV);                                                              \
00188     }                                                                           \
00189   }
00190 
00191 #define DO_UMULH  uemul64(RAV, RBV, &RCV);
00192 
00193 /* subtraction */
00194 #define DO_SUBQ   RCV = RAV - RBV;
00195 #define DO_S4SUBQ RCV = (RAV * 4) - RBV;
00196 #define DO_S8SUBQ RCV = (RAV * 8) - RBV;
00197 
00198 #define DO_SUBQ_V                                                               \
00199   {                                                                             \
00200     u64 rav = RAV;                                                              \
00201     u64 rbv = RBV;                                                              \
00202     RCV = rav - rbv;                                                            \
00203                                                                              \
00204     /* test for integer overflow */                                             \
00205     if(((rav ^ rbv) & (rav ^ RCV)) & Q_SIGN)                                    \
00206     {                                                                           \
00207       ARITH_TRAP_I(TRAP_IOV, RC);                                               \
00208       printf("SUBQ_V %016"LL "x - %016"LL "x = %016"LL "x + TRAP.\n", rav, rbv, \
00209              RCV);                                                              \
00210     }                                                                           \
00211   }
00212 
00213 #define DO_SUBL   RCV = sext_u64_32(RAV - RBV);
00214 #define DO_S4SUBL RCV = sext_u64_32((RAV * 4) - RBV);
00215 #define DO_S8SUBL RCV = sext_u64_32((RAV * 8) - RBV);
00216 
00217 #define DO_SUBL_V                                                               \
00218   {                                                                             \
00219     u64 rav = RAV;                                                              \
00220     u64 rbv = RBV;                                                              \
00221     RCV = sext_u64_32(rav - rbv);                                               \
00222                                                                              \
00223     /* test for integer overflow */                                             \
00224     if(((rav ^ rbv) & (rav ^ RCV)) & L_SIGN)                                    \
00225     {                                                                           \
00226       ARITH_TRAP_I(TRAP_IOV, RC);                                               \
00227       printf("SUBL_V %016"LL "x - %016"LL "x = %016"LL "x + TRAP.\n", rav, rbv, \
00228              RCV);                                                              \
00229     }                                                                           \
00230   }

SourceForge.net Logo
Project space on SourceForge.net