📄 prim_ops.c
字号:
CONDITIONAL_SET_FLAG(cf, F_CF); CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF); } return res;}/****************************************************************************REMARKS:Implements the RCR instruction and side effects.****************************************************************************/u8 rcr_byte(u8 d, u8 s){ u32 res, cnt; u32 mask, cf, ocf = 0; /* rotate right through carry */ /* s is the rotate distance. It varies from 0 - 8. d is the byte object rotated. have CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 The new rotate is done mod 9, and given this, for a rotation of n bits (mod 9) the new carry flag is then located n bits from the LSB. The low part is then shifted up cnt bits, and the high part is or'd in. Using CAPS for new values, and lowercase for the original values, this can be expressed as: IF n > 0 1) CF <- b_(n-1) 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ res = d; if ((cnt = s % 9) != 0) { /* extract the new CARRY FLAG. */ /* CF <- b_(n-1) */ if (cnt == 1) { cf = d & 0x1; /* note hackery here. Access_flag(..) evaluates to either 0 if flag not set non-zero if flag is set. doing access_flag(..) != 0 casts that into either 0..1 in any representation of the flags register (i.e. packed bit array or unpacked.) */ ocf = ACCESS_FLAG(F_CF) != 0; } else cf = (d >> (cnt - 1)) & 0x1; /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */ /* note that the right hand side done by the mask This is effectively done by shifting the object to the right. The result must be masked, in case the object came in and was treated as a negative number. Needed??? */ mask = (1 << (8 - cnt)) - 1; res = (d >> cnt) & mask; /* now the high stuff which rotated around into the positions B_cnt-2 .. B_0 */ /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ /* shift it downward, 7-(n-2) = 9-n positions. and mask off the result before or'ing in. */ res |= (d << (9 - cnt)); /* if the carry flag was set, or it in. */ if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ /* B_(8-n) <- cf */ res |= 1 << (8 - cnt); } /* set the new carry flag, based on the variable "cf" */ CONDITIONAL_SET_FLAG(cf, F_CF); /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and the most significant bit. Blecck. */ /* parenthesized... */ if (cnt == 1) { CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF); } } return (u8)res;}/****************************************************************************REMARKS:Implements the RCR instruction and side effects.****************************************************************************/u16 rcr_word(u16 d, u8 s){ u32 res, cnt; u32 mask, cf, ocf = 0; /* rotate right through carry */ res = d; if ((cnt = s % 17) != 0) { if (cnt == 1) { cf = d & 0x1; ocf = ACCESS_FLAG(F_CF) != 0; } else cf = (d >> (cnt - 1)) & 0x1; mask = (1 << (16 - cnt)) - 1; res = (d >> cnt) & mask; res |= (d << (17 - cnt)); if (ACCESS_FLAG(F_CF)) { res |= 1 << (16 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); if (cnt == 1) { CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF); } } return (u16)res;}/****************************************************************************REMARKS:Implements the RCR instruction and side effects.****************************************************************************/u32 rcr_long(u32 d, u8 s){ u32 res, cnt; u32 mask, cf, ocf = 0; /* rotate right through carry */ res = d; if ((cnt = s % 33) != 0) { if (cnt == 1) { cf = d & 0x1; ocf = ACCESS_FLAG(F_CF) != 0; } else cf = (d >> (cnt - 1)) & 0x1; mask = (1 << (32 - cnt)) - 1; res = (d >> cnt) & mask; if (cnt != 1) res |= (d << (33 - cnt)); if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ res |= 1 << (32 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); if (cnt == 1) { CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF); } } return res;}/****************************************************************************REMARKS:Implements the ROL instruction and side effects.****************************************************************************/u8 rol_byte(u8 d, u8 s){ register unsigned int res, cnt, mask; /* rotate left */ /* s is the rotate distance. It varies from 0 - 8. d is the byte object rotated. have CF B_7 ... B_0 The new rotate is done mod 8. Much simpler than the "rcl" or "rcr" operations. IF n > 0 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */ res = d; if ((cnt = s % 8) != 0) { /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */ res = (d << cnt); /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */ mask = (1 << cnt) - 1; res |= (d >> (8 - cnt)) & mask; /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x1, F_CF); /* OVERFLOW is set *IFF* s==1, then it is the xor of CF and the most significant bit. Blecck. */ CONDITIONAL_SET_FLAG(s == 1 && XOR2((res & 0x1) + ((res >> 6) & 0x2)), F_OF); } if (s != 0) { /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x1, F_CF); } return (u8)res;}/****************************************************************************REMARKS:Implements the ROL instruction and side effects.****************************************************************************/u16 rol_word(u16 d, u8 s){ register unsigned int res, cnt, mask; res = d; if ((cnt = s % 16) != 0) { res = (d << cnt); mask = (1 << cnt) - 1; res |= (d >> (16 - cnt)) & mask; CONDITIONAL_SET_FLAG(res & 0x1, F_CF); CONDITIONAL_SET_FLAG(s == 1 && XOR2((res & 0x1) + ((res >> 14) & 0x2)), F_OF); } if (s != 0) { /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x1, F_CF); } return (u16)res;}/****************************************************************************REMARKS:Implements the ROL instruction and side effects.****************************************************************************/u32 rol_long(u32 d, u8 s){ register u32 res, cnt, mask; res = d; if ((cnt = s % 32) != 0) { res = (d << cnt); mask = (1 << cnt) - 1; res |= (d >> (32 - cnt)) & mask; CONDITIONAL_SET_FLAG(res & 0x1, F_CF); CONDITIONAL_SET_FLAG(s == 1 && XOR2((res & 0x1) + ((res >> 30) & 0x2)), F_OF); } if (s != 0) { /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x1, F_CF); } return res;}/****************************************************************************REMARKS:Implements the ROR instruction and side effects.****************************************************************************/u8 ror_byte(u8 d, u8 s){ register unsigned int res, cnt, mask; /* rotate right */ /* s is the rotate distance. It varies from 0 - 8. d is the byte object rotated. have B_7 ... B_0 The rotate is done mod 8. IF n > 0 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */ res = d; if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */ /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */ res = (d << (8 - cnt)); /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */ mask = (1 << (8 - cnt)) - 1; res |= (d >> (cnt)) & mask; /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x80, F_CF); /* OVERFLOW is set *IFF* s==1, then it is the xor of the two most significant bits. Blecck. */ CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF); } else if (s != 0) { /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x80, F_CF); } return (u8)res;}/****************************************************************************REMARKS:Implements the ROR instruction and side effects.****************************************************************************/u16 ror_word(u16 d, u8 s){ register unsigned int res, cnt, mask; res = d; if ((cnt = s % 16) != 0) { res = (d << (16 - cnt)); mask = (1 << (16 - cnt)) - 1; res |= (d >> (cnt)) & mask; CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF); } else if (s != 0) { /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); } return (u16)res;}/****************************************************************************REMARKS:Implements the ROR instruction and side effects.****************************************************************************/u32 ror_long(u32 d, u8 s){ register u32 res, cnt, mask; res = d; if ((cnt = s % 32) != 0) { res = (d << (32 - cnt)); mask = (1 << (32 - cnt)) - 1; res |= (d >> (cnt)) & mask; CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF); } else if (s != 0) { /* set the new carry flag, Note that it is the low order bit of the result!!! */ CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); } return res;}/****************************************************************************REMARKS:Implements the SHL instruction and side effects.****************************************************************************/u8 shl_byte(u8 d, u8 s){ unsigned int cnt, res, cf; if (s < 8) { cnt = s % 8; /* last bit shifted out goes into carry flag */ if (cnt > 0) { res = d << cnt; cf = d & (1 << (8 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); CONDITIONAL_SET_FLAG(res & 0x80, F_SF); CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); } else { res = (u8) d; } if (cnt == 1) { /* Needs simplification. */ CONDITIONAL_SET_FLAG( (((res & 0x80) == 0x80) ^ (ACCESS_FLAG(F_CF) != 0)), /* was (M.x86.R_FLG&F_CF)==F_CF)), */ F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); } return (u8)res;}/****************************************************************************REMARKS:Implements the SHL instruction and side effects.****************************************************************************/u16 shl_word(u16 d, u8 s){ unsigned int cnt, res, cf; if (s < 16) { cnt = s % 16; if (cnt > 0) { res = d << cnt; cf = d & (1 << (16 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); } else { res = (u16) d; } if (cnt == 1) { CONDITIONAL_SET_FLAG( (((res & 0x8000) == 0x8000) ^ (ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); } return (u16)res;}/****************************************************************************REMARKS:Implements the SHL instruction and side effects.****************************************************************************/u32 shl_long(u32 d, u8 s){ unsigned int cnt, res, cf; if (s < 32) { cnt = s % 32; if (cnt > 0) { res = d << cnt; cf = d & (1 << (32 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); } else { res = d; } if (cnt == 1) { CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ (ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); } return res;}/****************************************************************************REMARKS:Implements the SHR instruction and side effects.****************************************************************************/u8 shr_byte(u8 d, u8 s){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -