123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257 |
- use cpu::cpu::*;
- use cpu::global_pointers::*;
- use cpu::memory::{read8, write8};
- use cpu::misc_instr::{getaf, getcf, getzf};
- pub fn int_log2(x: i32) -> i32 { 31 - x.leading_zeros() as i32 }
- #[no_mangle]
- pub unsafe fn add(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let res = dest_operand + source_operand;
- *last_op1 = dest_operand;
- *last_result = res & (2 << op_size) - 1;
- *last_op_size = op_size;
- *flags_changed = FLAGS_ALL;
- return res;
- }
- #[no_mangle]
- pub unsafe fn adc(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let cf = getcf() as i32;
- let res = dest_operand + source_operand + cf;
- *last_op1 = dest_operand;
- *last_result = res;
- *last_op_size = op_size;
- *flags_changed = FLAGS_ALL & !FLAG_CARRY & !FLAG_ADJUST & !FLAG_OVERFLOW;
- *flags = *flags & !FLAG_CARRY & !FLAG_ADJUST & !FLAG_OVERFLOW
- | (dest_operand ^ ((dest_operand ^ source_operand) & (source_operand ^ res))) >> op_size
- & FLAG_CARRY
- | (dest_operand ^ source_operand ^ res) & FLAG_ADJUST
- | ((source_operand ^ res) & (dest_operand ^ res)) >> op_size << 11 & FLAG_OVERFLOW;
- return res;
- }
- #[no_mangle]
- pub unsafe fn sub(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let res = dest_operand - source_operand;
- *last_op1 = dest_operand;
- *last_result = res & (2 << op_size) - 1;
- *last_op_size = op_size;
- *flags_changed = FLAGS_ALL | FLAG_SUB;
- return res;
- }
- #[no_mangle]
- pub unsafe fn sbb(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let cf = getcf() as i32;
- let res = dest_operand - source_operand - cf;
- *last_op1 = dest_operand;
- *last_result = res;
- *last_op_size = op_size;
- *flags_changed = FLAGS_ALL & !FLAG_CARRY & !FLAG_ADJUST & !FLAG_OVERFLOW | FLAG_SUB;
- *flags = *flags & !FLAG_CARRY & !FLAG_ADJUST & !FLAG_OVERFLOW
- | (res ^ ((res ^ source_operand) & (source_operand ^ dest_operand))) >> op_size
- & FLAG_CARRY
- | (dest_operand ^ source_operand ^ res) & FLAG_ADJUST
- | ((source_operand ^ dest_operand) & (res ^ dest_operand)) >> op_size << 11 & FLAG_OVERFLOW;
- return res;
- }
- #[no_mangle]
- pub unsafe fn add8(x: i32, y: i32) -> i32 { return add(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn add16(x: i32, y: i32) -> i32 { return add(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn add32(x: i32, y: i32) -> i32 { return add(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn sub8(x: i32, y: i32) -> i32 { return sub(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn sub16(x: i32, y: i32) -> i32 { return sub(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn sub32(x: i32, y: i32) -> i32 { return sub(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn adc8(x: i32, y: i32) -> i32 { return adc(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn adc16(x: i32, y: i32) -> i32 { return adc(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn adc32(x: i32, y: i32) -> i32 { return adc(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn sbb8(x: i32, y: i32) -> i32 { return sbb(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn sbb16(x: i32, y: i32) -> i32 { return sbb(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn sbb32(x: i32, y: i32) -> i32 { return sbb(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn cmp8(x: i32, y: i32) { sub(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn cmp16(x: i32, y: i32) { sub(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn cmp32(x: i32, y: i32) { sub(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn inc(dest_operand: i32, op_size: i32) -> i32 {
- *flags = *flags & !1 | getcf() as i32;
- let res = dest_operand + 1;
- *last_op1 = dest_operand;
- *last_result = res & (2 << op_size) - 1;
- *last_op_size = op_size;
- *flags_changed = FLAGS_ALL & !1;
- return res;
- }
- #[no_mangle]
- pub unsafe fn dec(dest_operand: i32, op_size: i32) -> i32 {
- *flags = *flags & !1 | getcf() as i32;
- let res = dest_operand - 1;
- *last_op1 = dest_operand;
- *last_result = res & (2 << op_size) - 1;
- *last_op_size = op_size;
- *flags_changed = FLAGS_ALL & !1 | FLAG_SUB;
- return res;
- }
- #[no_mangle]
- pub unsafe fn inc8(x: i32) -> i32 { return inc(x, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn inc16(x: i32) -> i32 { return inc(x, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn inc32(x: i32) -> i32 { return inc(x, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn dec8(x: i32) -> i32 { return dec(x, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn dec16(x: i32) -> i32 { return dec(x, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn dec32(x: i32) -> i32 { return dec(x, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn not8(x: i32) -> i32 { return !x; }
- #[no_mangle]
- pub unsafe fn not16(x: i32) -> i32 { return !x; }
- #[no_mangle]
- pub unsafe fn not32(x: i32) -> i32 { return !x; }
- #[no_mangle]
- pub unsafe fn neg(dest_operand: i32, op_size: i32) -> i32 { sub(0, dest_operand, op_size) }
- #[no_mangle]
- pub unsafe fn neg8(x: i32) -> i32 { return neg(x, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn neg16(x: i32) -> i32 { return neg(x, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn neg32(x: i32) -> i32 { return neg(x, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn mul8(source_operand: i32) {
- let result = source_operand * read_reg8(AL);
- write_reg16(AX, result);
- *last_result = result & 255;
- *last_op_size = OPSIZE_8;
- if result < 256 {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- else {
- *flags |= 1 | FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn imul8(source_operand: i32) {
- let result = source_operand * (read_reg8(AL) << 24 >> 24);
- write_reg16(AX, result);
- *last_result = result & 255;
- *last_op_size = OPSIZE_8;
- if result > 127 || result < -128 {
- *flags |= 1 | FLAG_OVERFLOW
- }
- else {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn mul16(source_operand: u32) {
- let result = source_operand.wrapping_mul(read_reg16(AX) as u32);
- let high_result = result >> 16;
- write_reg16(AX, result as i32);
- write_reg16(DX, high_result as i32);
- *last_result = (result & 0xFFFF) as i32;
- *last_op_size = OPSIZE_16;
- if high_result == 0 {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- else {
- *flags |= 1 | FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn imul16(source_operand: i32) {
- let result = source_operand * (read_reg16(AX) << 16 >> 16);
- write_reg16(AX, result);
- write_reg16(DX, result >> 16);
- *last_result = result & 0xFFFF;
- *last_op_size = OPSIZE_16;
- if result > 32767 || result < -32768 {
- *flags |= 1 | FLAG_OVERFLOW
- }
- else {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn imul_reg16(mut operand1: i32, mut operand2: i32) -> i32 {
- operand1 = operand1 << 16 >> 16;
- operand2 = operand2 << 16 >> 16;
- let result = operand1 * operand2;
- *last_result = result & 0xFFFF;
- *last_op_size = OPSIZE_16;
- if result > 32767 || result < -32768 {
- *flags |= 1 | FLAG_OVERFLOW
- }
- else {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- return result;
- }
- #[no_mangle]
- pub unsafe fn mul32(source_operand: i32) {
- let dest_operand = read_reg32(EAX);
- let result = (dest_operand as u32 as u64).wrapping_mul(source_operand as u32 as u64);
- let result_low = result as i32;
- let result_high = (result >> 32) as i32;
- write_reg32(EAX, result_low);
- write_reg32(EDX, result_high);
- *last_result = result_low;
- *last_op_size = OPSIZE_32;
- if result_high == 0 {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- else {
- *flags |= 1 | FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn imul32(source_operand: i32) {
- let dest_operand = read_reg32(EAX);
- let result = dest_operand as i64 * source_operand as i64;
- let result_low = result as i32;
- let result_high = (result >> 32) as i32;
- write_reg32(EAX, result_low);
- write_reg32(EDX, result_high);
- *last_result = result_low;
- *last_op_size = OPSIZE_32;
- if result_high == result_low >> 31 {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- else {
- *flags |= 1 | FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn imul_reg32(operand1: i32, operand2: i32) -> i32 {
- let result = operand1 as i64 * operand2 as i64;
- let result_low = result as i32;
- let result_high = (result >> 32) as i32;
- *last_result = result_low;
- *last_op_size = OPSIZE_32;
- if result_high == result_low >> 31 {
- *flags &= !1 & !FLAG_OVERFLOW
- }
- else {
- *flags |= 1 | FLAG_OVERFLOW
- }
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- return result_low;
- }
- #[no_mangle]
- pub unsafe fn xadd8(source_operand: i32, reg: i32) -> i32 {
- let tmp = read_reg8(reg);
- write_reg8(reg, source_operand);
- return add(source_operand, tmp, OPSIZE_8);
- }
- #[no_mangle]
- pub unsafe fn xadd16(source_operand: i32, reg: i32) -> i32 {
- let tmp = read_reg16(reg);
- write_reg16(reg, source_operand);
- return add(source_operand, tmp, OPSIZE_16);
- }
- #[no_mangle]
- pub unsafe fn xadd32(source_operand: i32, reg: i32) -> i32 {
- let tmp = read_reg32(reg);
- write_reg32(reg, source_operand);
- return add(source_operand, tmp, OPSIZE_32);
- }
- #[no_mangle]
- pub unsafe fn cmpxchg8(data: i32, r: i32) -> i32 {
- cmp8(read_reg8(AL), data);
- if getzf() {
- read_reg8(r)
- }
- else {
- write_reg8(AL, data);
- data
- }
- }
- #[no_mangle]
- pub unsafe fn cmpxchg16(data: i32, r: i32) -> i32 {
- cmp16(read_reg16(AX), data);
- if getzf() {
- read_reg16(r)
- }
- else {
- write_reg16(AX, data);
- data
- }
- }
- #[no_mangle]
- pub unsafe fn cmpxchg32(data: i32, r: i32) -> i32 {
- cmp32(read_reg32(EAX), data);
- if getzf() {
- read_reg32(r)
- }
- else {
- write_reg32(EAX, data);
- data
- }
- }
- #[no_mangle]
- pub unsafe fn bcd_daa() {
- let old_al = read_reg8(AL);
- let old_cf = getcf();
- let old_af = getaf();
- *flags &= !1 & !FLAG_ADJUST;
- if old_al & 15 > 9 || old_af {
- write_reg8(AL, read_reg8(AL) + 6);
- *flags |= FLAG_ADJUST
- }
- if old_al > 153 || old_cf {
- write_reg8(AL, read_reg8(AL) + 96);
- *flags |= 1
- }
- *last_result = read_reg8(AL);
- *last_op_size = OPSIZE_8;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_ADJUST & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn bcd_das() {
- let old_al = read_reg8(AL);
- let old_cf = getcf();
- *flags &= !1;
- if old_al & 15 > 9 || getaf() {
- write_reg8(AL, read_reg8(AL) - 6);
- *flags |= FLAG_ADJUST;
- *flags = *flags & !1 | old_cf as i32 | (old_al < 6) as i32
- }
- else {
- *flags &= !FLAG_ADJUST
- }
- if old_al > 153 || old_cf {
- write_reg8(AL, read_reg8(AL) - 96);
- *flags |= 1
- }
- *last_result = read_reg8(AL);
- *last_op_size = OPSIZE_8;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_ADJUST & !FLAG_OVERFLOW;
- }
- #[no_mangle]
- pub unsafe fn bcd_aad(imm8: i32) {
- let result = read_reg8(AL) + read_reg8(AH) * imm8;
- *last_result = result & 255;
- write_reg16(AX, *last_result);
- *last_op_size = OPSIZE_8;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_ADJUST & !FLAG_OVERFLOW;
- *flags &= !1 & !FLAG_ADJUST & !FLAG_OVERFLOW;
- if result > 0xFFFF {
- *flags |= 1
- };
- }
- #[no_mangle]
- pub unsafe fn bcd_aam(imm8: i32) {
- // ascii adjust after multiplication
- if imm8 == 0 {
- trigger_de();
- }
- else {
- let temp = read_reg8(AL);
- write_reg8(AH, temp as i32 / imm8);
- write_reg8(AL, temp as i32 % imm8);
- *last_result = read_reg8(AL);
- *flags_changed = FLAGS_ALL & !1 & !FLAG_ADJUST & !FLAG_OVERFLOW;
- *flags &= !1 & !FLAG_ADJUST & !FLAG_OVERFLOW
- };
- }
- #[no_mangle]
- pub unsafe fn bcd_aaa() {
- if read_reg8(AL) & 15 > 9 || getaf() {
- write_reg16(AX, read_reg16(AX) + 6);
- write_reg8(AH, read_reg8(AH) + 1);
- *flags |= FLAG_ADJUST | 1
- }
- else {
- *flags &= !FLAG_ADJUST & !1
- }
- write_reg8(AL, read_reg8(AL) & 15);
- *flags_changed &= !FLAG_ADJUST & !1;
- }
- #[no_mangle]
- pub unsafe fn bcd_aas() {
- if read_reg8(AL) & 15 > 9 || getaf() {
- write_reg16(AX, read_reg16(AX) - 6);
- write_reg8(AH, read_reg8(AH) - 1);
- *flags |= FLAG_ADJUST | 1
- }
- else {
- *flags &= !FLAG_ADJUST & !1
- }
- write_reg8(AL, read_reg8(AL) & 15);
- *flags_changed &= !FLAG_ADJUST & !1;
- }
- #[no_mangle]
- pub unsafe fn and(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let result = dest_operand & source_operand;
- *last_result = result;
- *last_op_size = op_size;
- *flags &= !1 & !FLAG_OVERFLOW & !FLAG_ADJUST;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW & !FLAG_ADJUST;
- return result;
- }
- #[no_mangle]
- pub unsafe fn or(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let result = dest_operand | source_operand;
- *last_result = result;
- *last_op_size = op_size;
- *flags &= !1 & !FLAG_OVERFLOW & !FLAG_ADJUST;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW & !FLAG_ADJUST;
- return result;
- }
- #[no_mangle]
- pub unsafe fn xor(dest_operand: i32, source_operand: i32, op_size: i32) -> i32 {
- let result = dest_operand ^ source_operand;
- *last_result = result;
- *last_op_size = op_size;
- *flags &= !1 & !FLAG_OVERFLOW & !FLAG_ADJUST;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW & !FLAG_ADJUST;
- return result;
- }
- #[no_mangle]
- pub unsafe fn and8(x: i32, y: i32) -> i32 { return and(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn and16(x: i32, y: i32) -> i32 { return and(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn and32(x: i32, y: i32) -> i32 { return and(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn test8(x: i32, y: i32) { and(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn test16(x: i32, y: i32) { and(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn test32(x: i32, y: i32) { and(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn or8(x: i32, y: i32) -> i32 { return or(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn or16(x: i32, y: i32) -> i32 { return or(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn or32(x: i32, y: i32) -> i32 { return or(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn xor8(x: i32, y: i32) -> i32 { return xor(x, y, OPSIZE_8); }
- #[no_mangle]
- pub unsafe fn xor16(x: i32, y: i32) -> i32 { return xor(x, y, OPSIZE_16); }
- #[no_mangle]
- pub unsafe fn xor32(x: i32, y: i32) -> i32 { return xor(x, y, OPSIZE_32); }
- #[no_mangle]
- pub unsafe fn rol8(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- count &= 7;
- let result = dest_operand << count | dest_operand >> 8 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result & 1
- | (result << 11 ^ result << 4) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rol16(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- count &= 15;
- let result = dest_operand << count | dest_operand >> 16 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result & 1
- | (result << 11 ^ result >> 4) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rol32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- let result = ((dest_operand << count) as u32 | dest_operand as u32 >> 32 - count) as i32;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result & 1
- | (result << 11 ^ result >> 20) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rcl8(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- count %= 9;
- if 0 == count {
- return dest_operand;
- }
- else {
- let result =
- dest_operand << count | (getcf() as i32) << count - 1 | dest_operand >> 9 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 8 & 1
- | (result << 3 ^ result << 4) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rcl16(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- count %= 17;
- if 0 == count {
- return dest_operand;
- }
- else {
- let result =
- dest_operand << count | (getcf() as i32) << count - 1 | dest_operand >> 17 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 16 & 1
- | (result >> 5 ^ result >> 4) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rcl32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- let mut result: i32 = dest_operand << count | (getcf() as i32) << count - 1;
- if count > 1 {
- result = (result as u32 | dest_operand as u32 >> 33 - count) as i32
- }
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- let b = (dest_operand as u32 >> 32 - count & 1) as i32;
- *flags = (*flags & !1 & !FLAG_OVERFLOW | b) | (b << 11 ^ result >> 20) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn ror8(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- count &= 7;
- let result = dest_operand >> count | dest_operand << 8 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 7 & 1
- | (result << 4 ^ result << 5) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn ror16(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- count &= 15;
- let result = dest_operand >> count | dest_operand << 16 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 15 & 1
- | (result >> 4 ^ result >> 3) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn ror32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- let result = (dest_operand as u32 >> count | (dest_operand << 32 - count) as u32) as i32;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 31 & 1
- | (result >> 20 ^ result >> 19) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rcr8(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- count %= 9;
- if 0 == count {
- return dest_operand;
- }
- else {
- let result =
- dest_operand >> count | (getcf() as i32) << 8 - count | dest_operand << 9 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 8 & 1
- | (result << 4 ^ result << 5) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rcr16(dest_operand: i32, mut count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- count %= 17;
- if 0 == count {
- return dest_operand;
- }
- else {
- let result =
- dest_operand >> count | (getcf() as i32) << 16 - count | dest_operand << 17 - count;
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 16 & 1
- | (result >> 4 ^ result >> 3) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn rcr32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if 0 == count {
- return dest_operand;
- }
- else {
- let mut result: i32 =
- (dest_operand as u32 >> count | ((getcf() as i32) << 32 - count) as u32) as i32;
- if count > 1 {
- result |= dest_operand << 33 - count
- }
- *flags_changed &= !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | dest_operand >> count - 1 & 1
- | (result >> 20 ^ result >> 19) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn div8(source_operand: u32) {
- if source_operand == 0 {
- trigger_de();
- return;
- }
- else {
- let target_operand = read_reg16(AX);
- let result = (target_operand as u32).wrapping_div(source_operand) as u16;
- if result as i32 >= 256 {
- trigger_de();
- }
- else {
- write_reg8(AL, result as i32);
- write_reg8(
- AH,
- (target_operand as u32).wrapping_rem(source_operand) as i32,
- );
- }
- return;
- };
- }
- #[no_mangle]
- pub unsafe fn idiv8(source_operand: i32) {
- if source_operand == 0 {
- trigger_de();
- return;
- }
- else {
- let target_operand = read_reg16(AX) << 16 >> 16;
- let result = target_operand / source_operand;
- if result >= 128 || result <= -129 {
- trigger_de();
- }
- else {
- write_reg8(AL, result);
- write_reg8(AH, target_operand % source_operand);
- }
- return;
- };
- }
- #[no_mangle]
- pub unsafe fn div16_without_fault(source_operand: u32) -> bool {
- if source_operand == 0 {
- return false;
- }
- let target_operand = (read_reg16(AX) | read_reg16(DX) << 16) as u32;
- let result = target_operand.wrapping_div(source_operand);
- if result >= 0x10000 {
- return false;
- }
- write_reg16(AX, result as i32);
- write_reg16(DX, target_operand.wrapping_rem(source_operand) as i32);
- return true;
- }
- pub unsafe fn div16(source_operand: u32) {
- if !div16_without_fault(source_operand) {
- trigger_de()
- }
- }
- #[no_mangle]
- pub unsafe fn idiv16_without_fault(source_operand: i32) -> bool {
- if source_operand == 0 {
- return false;
- }
- let target_operand = read_reg16(AX) | read_reg16(DX) << 16;
- let result = target_operand / source_operand;
- if result >= 32768 || result <= -32769 {
- return false;
- }
- write_reg16(AX, result);
- write_reg16(DX, (target_operand % source_operand) as i32);
- return true;
- }
- pub unsafe fn idiv16(source_operand: i32) {
- if !idiv16_without_fault(source_operand) {
- trigger_de()
- }
- }
- #[no_mangle]
- pub unsafe fn div32_without_fault(source_operand: u32) -> bool {
- if source_operand == 0 {
- return false;
- }
- let target_low = read_reg32(EAX) as u32;
- let target_high = read_reg32(EDX) as u32;
- let target_operand = (target_high as u64) << 32 | target_low as u64;
- let result = target_operand.wrapping_div(source_operand as u64);
- if result > 0xFFFFFFFF {
- return false;
- }
- let mod_0 = target_operand.wrapping_rem(source_operand as u64) as i32;
- write_reg32(EAX, result as i32);
- write_reg32(EDX, mod_0);
- return true;
- }
- pub unsafe fn div32(source_operand: u32) {
- if !div32_without_fault(source_operand) {
- trigger_de()
- }
- }
- #[no_mangle]
- pub unsafe fn idiv32_without_fault(source_operand: i32) -> bool {
- if source_operand == 0 {
- return false;
- }
- let target_low = read_reg32(EAX) as u32;
- let target_high = read_reg32(EDX) as u32;
- let target_operand = ((target_high as u64) << 32 | target_low as u64) as i64;
- if source_operand == -1 && target_operand == -0x80000000_00000000 as i64 {
- return false;
- }
- let result = target_operand / source_operand as i64;
- if result < -0x80000000 || result > 0x7FFFFFFF {
- return false;
- }
- let mod_0 = (target_operand % source_operand as i64) as i32;
- write_reg32(EAX, result as i32);
- write_reg32(EDX, mod_0);
- return true;
- }
- pub unsafe fn idiv32(source_operand: i32) {
- if !idiv32_without_fault(source_operand) {
- trigger_de()
- }
- }
- #[no_mangle]
- pub unsafe fn shl8(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = dest_operand << count;
- *last_result = result;
- *last_op_size = OPSIZE_8;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 8 & 1
- | (result << 3 ^ result << 4) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shl16(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = dest_operand << count;
- *last_result = result;
- *last_op_size = OPSIZE_16;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | result >> 16 & 1
- | (result >> 5 ^ result >> 4) & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shl32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = dest_operand << count;
- *last_result = result;
- *last_op_size = OPSIZE_32;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- let b = dest_operand >> 32 - count & 1;
- *flags = *flags & !1 & !FLAG_OVERFLOW | b | (b ^ result >> 31 & 1) << 11 & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shr8(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = dest_operand >> count;
- *last_result = result;
- *last_op_size = OPSIZE_8;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | dest_operand >> count - 1 & 1
- | (dest_operand >> 7 & 1) << 11 & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shr16(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = dest_operand >> count;
- *last_result = result;
- *last_op_size = OPSIZE_16;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = *flags & !1 & !FLAG_OVERFLOW
- | dest_operand >> count - 1 & 1
- | dest_operand >> 4 & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shr32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = (dest_operand as u32 >> count) as i32;
- *last_result = result;
- *last_op_size = OPSIZE_32;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = (*flags & !1 & !FLAG_OVERFLOW)
- | (dest_operand as u32 >> count - 1 & 1) as i32
- | (dest_operand >> 20 & FLAG_OVERFLOW);
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn sar8(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result;
- if count < 8 {
- result = dest_operand << 24 >> count + 24;
- // of is zero
- *flags = *flags & !1 & !FLAG_OVERFLOW | dest_operand >> count - 1 & 1
- }
- else {
- result = dest_operand << 24 >> 31;
- *flags = *flags & !1 & !FLAG_OVERFLOW | result & 1
- }
- *last_result = result;
- *last_op_size = OPSIZE_8;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn sar16(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result;
- if count < 16 {
- result = dest_operand << 16 >> count + 16;
- *flags = *flags & !1 & !FLAG_OVERFLOW | dest_operand >> count - 1 & 1
- }
- else {
- result = dest_operand << 16 >> 31;
- *flags = *flags & !1 & !FLAG_OVERFLOW | result & 1
- }
- *last_result = result;
- *last_op_size = OPSIZE_16;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn sar32(dest_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = dest_operand >> count;
- *last_result = result;
- *last_op_size = OPSIZE_32;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = (*flags & !1 & !FLAG_OVERFLOW) | (dest_operand as u32 >> count - 1 & 1) as i32;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shrd16(dest_operand: i32, source_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result;
- if count <= 16 {
- result = dest_operand >> count | source_operand << 16 - count;
- *flags = *flags & !1 | dest_operand >> count - 1 & 1
- }
- else {
- result = dest_operand << 32 - count | source_operand >> count - 16;
- *flags = *flags & !1 | source_operand >> count - 17 & 1
- }
- *last_result = result;
- *last_op_size = OPSIZE_16;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = *flags & !FLAG_OVERFLOW | (result ^ dest_operand) >> 4 & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shrd32(dest_operand: i32, source_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = (dest_operand as u32 >> count | (source_operand << 32 - count) as u32) as i32;
- *last_result = result;
- *last_op_size = OPSIZE_32;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = ((*flags & !1 & !FLAG_OVERFLOW) | (dest_operand as u32 >> count - 1 & 1) as i32)
- | (result ^ dest_operand) >> 20 & FLAG_OVERFLOW;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shld16(dest_operand: i32, source_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result;
- if count <= 16 {
- result = ((dest_operand << count) as u32 | source_operand as u32 >> 16 - count) as i32;
- *flags = (*flags & !1) | (dest_operand as u32 >> 16 - count & 1) as i32;
- }
- else {
- result = dest_operand >> 32 - count | source_operand << count - 16;
- *flags = (*flags & !1) | (source_operand as u32 >> 32 - count & 1) as i32;
- }
- *last_result = result;
- *last_op_size = OPSIZE_16;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = *flags & !FLAG_OVERFLOW | (*flags & 1 ^ result >> 15 & 1) << 11;
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn shld32(dest_operand: i32, source_operand: i32, count: i32) -> i32 {
- dbg_assert!(count >= 0 && count < 32);
- if count == 0 {
- return dest_operand;
- }
- else {
- let result = ((dest_operand << count) as u32 | source_operand as u32 >> 32 - count) as i32;
- *last_result = result;
- *last_op_size = OPSIZE_32;
- *flags_changed = FLAGS_ALL & !1 & !FLAG_OVERFLOW;
- *flags = (*flags & !1) | (dest_operand as u32 >> 32 - count & 1) as i32;
- if count == 1 {
- *flags = *flags & !FLAG_OVERFLOW | (*flags & 1 ^ result >> 31 & 1) << 11
- }
- else {
- *flags &= !FLAG_OVERFLOW
- }
- return result;
- };
- }
- #[no_mangle]
- pub unsafe fn bt_reg(bit_base: i32, bit_offset: i32) {
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- }
- #[no_mangle]
- pub unsafe fn btc_reg(bit_base: i32, bit_offset: i32) -> i32 {
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- return bit_base ^ 1 << bit_offset;
- }
- #[no_mangle]
- pub unsafe fn bts_reg(bit_base: i32, bit_offset: i32) -> i32 {
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- return bit_base | 1 << bit_offset;
- }
- #[no_mangle]
- pub unsafe fn btr_reg(bit_base: i32, bit_offset: i32) -> i32 {
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- return bit_base & !(1 << bit_offset);
- }
- #[no_mangle]
- pub unsafe fn bt_mem(virt_addr: i32, mut bit_offset: i32) {
- let bit_base = return_on_pagefault!(safe_read8(virt_addr + (bit_offset >> 3)));
- bit_offset &= 7;
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- }
- #[no_mangle]
- pub unsafe fn btc_mem(virt_addr: i32, mut bit_offset: i32) {
- let phys_addr = return_on_pagefault!(translate_address_write(virt_addr + (bit_offset >> 3)));
- let bit_base = read8(phys_addr);
- bit_offset &= 7;
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- write8(phys_addr, bit_base ^ 1 << bit_offset);
- }
- #[no_mangle]
- pub unsafe fn btr_mem(virt_addr: i32, mut bit_offset: i32) {
- let phys_addr = return_on_pagefault!(translate_address_write(virt_addr + (bit_offset >> 3)));
- let bit_base = read8(phys_addr);
- bit_offset &= 7;
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- write8(phys_addr, bit_base & !(1 << bit_offset));
- }
- #[no_mangle]
- pub unsafe fn bts_mem(virt_addr: i32, mut bit_offset: i32) {
- let phys_addr = return_on_pagefault!(translate_address_write(virt_addr + (bit_offset >> 3)));
- let bit_base = read8(phys_addr);
- bit_offset &= 7;
- *flags = *flags & !1 | bit_base >> bit_offset & 1;
- *flags_changed &= !1;
- write8(phys_addr, bit_base | 1 << bit_offset);
- }
- #[no_mangle]
- pub unsafe fn bsf16(old: i32, bit_base: i32) -> i32 {
- *flags_changed = FLAGS_ALL & !FLAG_ZERO & !FLAG_CARRY;
- *flags &= !FLAG_CARRY;
- *last_op_size = OPSIZE_16;
- if bit_base == 0 {
- *flags |= FLAG_ZERO;
- *last_result = bit_base;
- // not defined in the docs, but value doesn't change on my intel machine
- return old;
- }
- else {
- *flags &= !FLAG_ZERO;
- *last_result = int_log2(-bit_base & bit_base);
- return *last_result;
- };
- }
- #[no_mangle]
- pub unsafe fn bsf32(old: i32, bit_base: i32) -> i32 {
- *flags_changed = FLAGS_ALL & !FLAG_ZERO & !FLAG_CARRY;
- *flags &= !FLAG_CARRY;
- *last_op_size = OPSIZE_32;
- if bit_base == 0 {
- *flags |= FLAG_ZERO;
- *last_result = bit_base;
- return old;
- }
- else {
- *flags &= !FLAG_ZERO;
- *last_result = int_log2(-bit_base & bit_base);
- return *last_result;
- };
- }
- #[no_mangle]
- pub unsafe fn bsr16(old: i32, bit_base: i32) -> i32 {
- *flags_changed = FLAGS_ALL & !FLAG_ZERO & !FLAG_CARRY;
- *flags &= !FLAG_CARRY;
- *last_op_size = OPSIZE_16;
- if bit_base == 0 {
- *flags |= FLAG_ZERO;
- *last_result = bit_base;
- return old;
- }
- else {
- *flags &= !FLAG_ZERO;
- *last_result = int_log2(bit_base);
- return *last_result;
- };
- }
- #[no_mangle]
- pub unsafe fn bsr32(old: i32, bit_base: i32) -> i32 {
- *flags_changed = FLAGS_ALL & !FLAG_ZERO & !FLAG_CARRY;
- *flags &= !FLAG_CARRY;
- *last_op_size = OPSIZE_32;
- if bit_base == 0 {
- *flags |= FLAG_ZERO;
- *last_result = bit_base;
- return old;
- }
- else {
- *flags &= !FLAG_ZERO;
- *last_result = int_log2(bit_base);
- return *last_result;
- };
- }
- #[no_mangle]
- pub unsafe fn popcnt(v: i32) -> i32 {
- *flags_changed = 0;
- *flags &= !FLAGS_ALL;
- if 0 != v {
- return v.count_ones() as i32;
- }
- else {
- *flags |= FLAG_ZERO;
- return 0;
- };
- }
- #[no_mangle]
- pub unsafe fn saturate_sw_to_ub(v: u16) -> u8 {
- let mut ret = v;
- if ret >= 32768 {
- ret = 0
- }
- else if ret > 255 {
- ret = 255
- }
- return ret as u8;
- }
- #[no_mangle]
- pub unsafe fn saturate_sw_to_sb(v: i32) -> u8 {
- dbg_assert!(v as u32 & 0xFFFF_0000 == 0);
- let mut ret: i32 = v;
- if ret > 65408 {
- ret = ret & 255
- }
- else if ret > 32767 {
- ret = 128
- }
- else if ret > 127 {
- ret = 127
- }
- dbg_assert!(ret as u32 & 0xFFFF_FF00 == 0);
- return ret as u8;
- }
- #[no_mangle]
- pub unsafe fn saturate_sd_to_sw(v: u32) -> u16 {
- let mut ret: u32 = v;
- if ret > 4294934528 {
- ret = ret & 0xFFFF
- }
- else if ret > 0x7FFFFFFF {
- ret = 32768
- }
- else if ret > 32767 {
- ret = 32767
- }
- dbg_assert!(ret & 0xFFFF_0000 == 0);
- return ret as u16;
- }
- #[no_mangle]
- pub unsafe fn saturate_sd_to_sb(v: u32) -> i8 {
- let mut ret: u32 = v;
- if ret > 0xFFFFFF80 {
- ret = ret & 255
- }
- else if ret > 0x7FFFFFFF {
- ret = 128
- }
- else if ret > 127 {
- ret = 127
- }
- dbg_assert!(ret & 0xFFFF_FF00 == 0);
- return ret as i8;
- }
- #[no_mangle]
- pub unsafe fn saturate_sd_to_ub(v: i32) -> i32 {
- let mut ret: i32 = v;
- if ret < 0 {
- ret = 0
- }
- dbg_assert!(ret as u32 & 0xFFFF_FF00 == 0);
- return ret;
- }
- #[no_mangle]
- pub unsafe fn saturate_ud_to_ub(v: u32) -> u8 {
- let mut ret: u32 = v;
- if ret > 255 {
- ret = 255
- }
- dbg_assert!(ret & 0xFFFF_FF00 == 0);
- return ret as u8;
- }
- #[no_mangle]
- pub unsafe fn saturate_uw(v: u32) -> u16 {
- let mut ret: u32 = v;
- if ret > 0x7FFFFFFF {
- ret = 0
- }
- else if ret > 0xFFFF {
- ret = 0xFFFF
- }
- dbg_assert!(ret & 0xFFFF_0000 == 0);
- return ret as u16;
- }
|