@@ -195,79 +195,54 @@ void DoShift(int opcode, u32& operand, u8 amount, int& carry, bool immediate) {
195
195
}
196
196
197
197
void LSL (u32 & operand, u8 amount, int & carry) {
198
- if (amount == 0 ) return ;
199
-
200
- if (amount >= 32 ) {
201
- if (amount > 32 ) {
202
- carry = 0 ;
203
- } else {
204
- carry = operand & 1 ;
205
- }
206
- operand = 0 ;
207
- return ;
198
+ const int adj_amount = std::min<int >(amount, 33 );
199
+ const u32 result = (u32 )((u64 )operand << adj_amount);
200
+ if (adj_amount != 0 ) {
201
+ carry = (u32 )((u64 )operand << (adj_amount - 1 )) >> 31 ;
208
202
}
209
-
210
- carry = (operand << (amount - 1 )) >> 31 ;
211
- operand <<= amount;
203
+ operand = result;
212
204
}
213
205
214
206
void LSR (u32 & operand, u8 amount, int & carry, bool immediate) {
215
- if (amount == 0 ) {
216
- // LSR #0 equals to LSR #32
217
- if (immediate) {
218
- amount = 32 ;
219
- } else {
220
- return ;
221
- }
207
+ // LSR #32 is encoded as LSR #0
208
+ if (immediate && amount == 0 ) {
209
+ amount = 32 ;
222
210
}
223
211
224
- if (amount >= 32 ) {
225
- if (amount > 32 ) {
226
- carry = 0 ;
227
- } else {
228
- carry = operand >> 31 ;
229
- }
230
- operand = 0 ;
231
- return ;
212
+ const int adj_amount = std::min<int >(amount, 33 );
213
+ const u32 result = (u32 )((u64 )operand >> adj_amount);
214
+ if (adj_amount != 0 ) {
215
+ carry = ((u64 )operand >> (adj_amount - 1 )) & 1u ;
232
216
}
233
-
234
- carry = (operand >> (amount - 1 )) & 1 ;
235
- operand >>= amount;
217
+ operand = result;
236
218
}
237
219
238
220
void ASR (u32 & operand, u8 amount, int & carry, bool immediate) {
239
- if (amount == 0 ) {
240
- // ASR #0 equals to ASR #32
241
- if (immediate) {
242
- amount = 32 ;
243
- } else {
244
- return ;
245
- }
221
+ // ASR #32 is encoded as ASR #0
222
+ if (immediate && amount == 0 ) {
223
+ amount = 32 ;
246
224
}
247
225
248
- int msb = operand >> 31 ;
249
-
250
- if (amount >= 32 ) {
251
- carry = msb;
252
- operand = 0xFFFFFFFF * msb;
253
- return ;
226
+ const int adj_amount = std::min<int >(amount, 33 );
227
+ const u32 result = (u32 )((s64)(s32)operand >> adj_amount);
228
+ if (adj_amount != 0 ) {
229
+ carry = ((s64)(s32)operand >> (adj_amount - 1 )) & 1u ;
254
230
}
255
-
256
- carry = (operand >> (amount - 1 )) & 1 ;
257
- operand = (operand >> amount) | ((0xFFFFFFFF * msb) << (32 - amount));
231
+ operand = result;
258
232
}
259
233
260
234
void ROR (u32 & operand, u8 amount, int & carry, bool immediate) {
261
- // ROR #0 equals to RRX #1
262
- if (amount != 0 || !immediate) {
263
- if (amount == 0 ) return ;
264
-
265
- amount %= 32 ;
266
- operand = (operand >> amount) | (operand << (32 - amount));
267
- carry = operand >> 31 ;
268
- } else {
269
- auto lsb = operand & 1 ;
235
+ // RRX #1 is encoded as ROR #0
236
+ if (immediate && amount == 0 ) {
237
+ const int lsb = operand & 1 ;
270
238
operand = (operand >> 1 ) | (carry << 31 );
271
239
carry = lsb;
240
+ } else {
241
+ if (amount == 0 ) {
242
+ return ;
243
+ }
244
+ const int adj_amount = amount & 31 ;
245
+ operand = (operand >> adj_amount) | (operand << ((32 - adj_amount) & 31 ));
246
+ carry = operand >> 31 ;
272
247
}
273
248
}
0 commit comments