Clean up binary operations.
Clean up binary operations.
1.1 --- a/jitcraft/Interpreter.cpp Tue Jul 17 00:49:24 2012 -0700
1.2 +++ b/jitcraft/Interpreter.cpp Tue Jul 17 03:18:32 2012 -0700
1.3 @@ -55,6 +55,18 @@
1.4 return value;
1.5 }
1.6
1.7 +// Pawn's original semantics specify some kind of floor operation, so
1.8 +// (8 / -3 == -3) and (-8 / 3 == -1). The SourcePawn 1 compiler (spcomp) uses
1.9 +// the upstream algorithm when constant folding. However the SourcePawn 1 JIT
1.10 +// does not. My guess is that Borja freaked out seeing the 13-instruction x86
1.11 +// sequence necessary to get this functionality (I vaguely recall a thread
1.12 +// where we discussed this with Mark Peter? But the ITB forums are gone...),
1.13 +// and we just decided to break the damn thing. So SP1 was inconsistent, but
1.14 +// we are not. And for completeness, we assert that the C compiler does the
1.15 +// right thing, since C89 leaves it unspecified.
1.16 +STATIC_ASSERT(8 / -3 == -2);
1.17 +STATIC_ASSERT(-8 / 3 == -2);
1.18 +
1.19 static inline bool
1.20 PushNewRef(Zone *zone, Top &top, void *location, Heap::Tenure tenure)
1.21 {
1.22 @@ -331,41 +343,33 @@
1.23
1.24 case OP_ADD:
1.25 {
1.26 - int right = POP_I32(top);
1.27 - int left = POP_I32(top);
1.28 - int result = left + right;
1.29 - PUSH_I32(top, result);
1.30 + top.sp[-2].i32 = top.sp[-2].i32 + top.sp[-1].i32;
1.31 + top.sp--;
1.32 break;
1.33 }
1.34
1.35 case OP_SUB:
1.36 {
1.37 - int right = POP_I32(top);
1.38 - int left = POP_I32(top);
1.39 - int result = left - right;
1.40 - PUSH_I32(top, result);
1.41 + top.sp[-2].i32 = top.sp[-2].i32 - top.sp[-1].i32;
1.42 + top.sp--;
1.43 break;
1.44 }
1.45
1.46 case OP_MUL:
1.47 {
1.48 - int right = POP_I32(top);
1.49 - int left = POP_I32(top);
1.50 - int result = left * right;
1.51 - PUSH_I32(top, result);
1.52 + top.sp[-2].i32 = top.sp[-2].i32 * top.sp[-1].i32;
1.53 + top.sp--;
1.54 break;
1.55 }
1.56
1.57 case OP_DIV:
1.58 {
1.59 - int right = POP_I32(top);
1.60 - int left = POP_I32(top);
1.61 - if (!right) {
1.62 + if (top.sp[-1].i32 == 0) {
1.63 zone->reportError(Message_IntegerDivideByZero);
1.64 goto error;
1.65 }
1.66 - int result = left / right;
1.67 - PUSH_I32(top, result);
1.68 + top.sp[-2].i32 = top.sp[-2].i32 / top.sp[-1].i32;
1.69 + top.sp--;
1.70 break;
1.71 }
1.72
1.73 @@ -413,37 +417,29 @@
1.74
1.75 case OP_ADD_F:
1.76 {
1.77 - float right = POP_F(top);
1.78 - float left = POP_F(top);
1.79 - float result = left + right;
1.80 - PUSH_F(top, result);
1.81 + top.sp[-2].f = top.sp[-2].f + top.sp[-1].f;
1.82 + top.sp--;
1.83 break;
1.84 }
1.85
1.86 case OP_SUB_F:
1.87 {
1.88 - float right = POP_F(top);
1.89 - float left = POP_F(top);
1.90 - float result = left - right;
1.91 - PUSH_F(top, result);
1.92 + top.sp[-2].f = top.sp[-2].f - top.sp[-1].f;
1.93 + top.sp--;
1.94 break;
1.95 }
1.96
1.97 case OP_MUL_F:
1.98 {
1.99 - float right = POP_F(top);
1.100 - float left = POP_F(top);
1.101 - float result = left * right;
1.102 - PUSH_F(top, result);
1.103 + top.sp[-2].f = top.sp[-2].f * top.sp[-1].f;
1.104 + top.sp--;
1.105 break;
1.106 }
1.107
1.108 case OP_DIV_F:
1.109 {
1.110 - float right = POP_F(top);
1.111 - float left = POP_F(top);
1.112 - float result = left / right;
1.113 - PUSH_F(top, result);
1.114 + top.sp[-2].f = top.sp[-2].f / top.sp[-1].f;
1.115 + top.sp--;
1.116 break;
1.117 }
1.118
1.119 @@ -491,55 +487,43 @@
1.120
1.121 case OP_SHL:
1.122 {
1.123 - int right = POP_I32(top);
1.124 - int left = POP_I32(top);
1.125 - int result = left << right;
1.126 - PUSH_I32(top, result);
1.127 + top.sp[-2].i32 = top.sp[-2].i32 << top.sp[-1].i32;
1.128 + top.sp--;
1.129 break;
1.130 }
1.131
1.132 case OP_SHR:
1.133 {
1.134 - int right = POP_I32(top);
1.135 - int left = POP_I32(top);
1.136 - int result = left >> right;
1.137 - PUSH_I32(top, result);
1.138 + top.sp[-2].i32 = top.sp[-2].i32 >> top.sp[-1].i32;
1.139 + top.sp--;
1.140 break;
1.141 }
1.142
1.143 case OP_USHR:
1.144 {
1.145 - int right = POP_I32(top);
1.146 - int left = POP_I32(top);
1.147 - int result = unsigned(left) >> unsigned(right);
1.148 - PUSH_I32(top, result);
1.149 + top.sp[-2].i32 = unsigned(top.sp[-2].i32) << unsigned(top.sp[-1].i32);
1.150 + top.sp--;
1.151 break;
1.152 }
1.153
1.154 case OP_BITAND:
1.155 {
1.156 - int right = POP_I32(top);
1.157 - int left = POP_I32(top);
1.158 - int result = left & right;
1.159 - PUSH_I32(top, result);
1.160 + top.sp[-2].i32 = top.sp[-2].i32 & top.sp[-1].i32;
1.161 + top.sp--;
1.162 break;
1.163 }
1.164
1.165 case OP_BITOR:
1.166 {
1.167 - int right = POP_I32(top);
1.168 - int left = POP_I32(top);
1.169 - int result = left | right;
1.170 - PUSH_I32(top, result);
1.171 + top.sp[-2].i32 = top.sp[-2].i32 | top.sp[-1].i32;
1.172 + top.sp--;
1.173 break;
1.174 }
1.175
1.176 case OP_BITXOR:
1.177 {
1.178 - int right = POP_I32(top);
1.179 - int left = POP_I32(top);
1.180 - int result = left ^ right;
1.181 - PUSH_I32(top, result);
1.182 + top.sp[-2].i32 = top.sp[-2].i32 ^ top.sp[-1].i32;
1.183 + top.sp--;
1.184 break;
1.185 }
1.186