port shift functions etc. from arith.js
This commit is contained in:
parent
c866462bd6
commit
3140cce77f
|
@ -172,21 +172,7 @@ function V86Starter(options)
|
|||
"_virt_boundary_write32": function() { return cpu.virt_boundary_write32.apply(cpu, arguments); },
|
||||
"_getiopl": function() { return cpu.getiopl.apply(cpu, arguments); },
|
||||
"_vm86_mode": function() { return cpu.vm86_mode.apply(cpu, arguments); },
|
||||
"_shl8": function() { return cpu.shl8.apply(cpu, arguments); },
|
||||
"_shr8": function() { return cpu.shr8.apply(cpu, arguments); },
|
||||
"_sar8": function() { return cpu.sar8.apply(cpu, arguments); },
|
||||
"_shl16": function() { return cpu.shl16.apply(cpu, arguments); },
|
||||
"_shr16": function() { return cpu.shr16.apply(cpu, arguments); },
|
||||
"_sar16": function() { return cpu.sar16.apply(cpu, arguments); },
|
||||
"_shl32": function() { return cpu.shl32.apply(cpu, arguments); },
|
||||
"_shr32": function() { return cpu.shr32.apply(cpu, arguments); },
|
||||
"_sar32": function() { return cpu.sar32.apply(cpu, arguments); },
|
||||
|
||||
"_shrd16": function() { return cpu.shrd16.apply(cpu, arguments); },
|
||||
"_shrd32": function() { return cpu.shrd32.apply(cpu, arguments); },
|
||||
"_shld16": function() { return cpu.shld16.apply(cpu, arguments); },
|
||||
"_shld32": function() { return cpu.shld32.apply(cpu, arguments); },
|
||||
|
||||
|
||||
"_bt_reg": function() { return cpu.bt_reg.apply(cpu, arguments); },
|
||||
"_bt_mem": function() { return cpu.bt_mem.apply(cpu, arguments); },
|
||||
"_btr_reg": function() { return cpu.btr_reg.apply(cpu, arguments); },
|
||||
|
|
14
src/cpu.js
14
src/cpu.js
|
@ -279,6 +279,20 @@ CPU.prototype.wasm_patch = function(wm)
|
|||
this.trigger_de = this.wm.funcs['_trigger_de'];
|
||||
this.trigger_gp = this.wm.funcs['_trigger_gp'];
|
||||
|
||||
this.shl8 = this.wm.funcs['_shl8'];
|
||||
this.shl16 = this.wm.funcs['_shl16'];
|
||||
this.shl32 = this.wm.funcs['_shl32'];
|
||||
this.shr8 = this.wm.funcs['_shr8'];
|
||||
this.shr16 = this.wm.funcs['_shr16'];
|
||||
this.shr32 = this.wm.funcs['_shr32'];
|
||||
this.sar8 = this.wm.funcs['_sar8'];
|
||||
this.sar16 = this.wm.funcs['_sar16'];
|
||||
this.sar32 = this.wm.funcs['_sar32'];
|
||||
this.shrd16 = this.wm.funcs['_shrd16'];
|
||||
this.shrd32 = this.wm.funcs['_shrd32'];
|
||||
this.shld16 = this.wm.funcs['_shld16'];
|
||||
this.shld32 = this.wm.funcs['_shld32'];
|
||||
|
||||
this.do_many_cycles_unsafe = this.wm.funcs['_do_many_cycles_unsafe'];
|
||||
|
||||
this.read_imm8 = this.wm.funcs['_read_imm8'];
|
||||
|
|
|
@ -823,3 +823,268 @@ void div16(uint32_t source_operand)
|
|||
}
|
||||
}
|
||||
|
||||
int32_t shl8(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand << count;
|
||||
|
||||
*last_op_size = OPSIZE_8;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW)
|
||||
| (*last_result >> 8 & 1)
|
||||
| (*last_result << 3 ^ *last_result << 4) & FLAG_OVERFLOW;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shl16(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand << count;
|
||||
|
||||
*last_op_size = OPSIZE_16;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW)
|
||||
| (*last_result >> 16 & 1)
|
||||
| (*last_result >> 5 ^ *last_result >> 4) & FLAG_OVERFLOW;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shl32(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand << count;
|
||||
|
||||
*last_op_size = OPSIZE_32;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
// test this
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW) | (dest_operand >> (32 - count) & 1);
|
||||
*flags |= ((*flags & 1) ^ (*last_result >> 31 & 1)) << 11 & FLAG_OVERFLOW;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shr8(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand >> count;
|
||||
|
||||
*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 *last_result;
|
||||
}
|
||||
|
||||
int32_t shr16(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand >> count;
|
||||
|
||||
*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 *last_result;
|
||||
}
|
||||
|
||||
int32_t shr32(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = ((uint32_t) dest_operand) >> count;
|
||||
|
||||
*last_op_size = OPSIZE_32;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW)
|
||||
| (((uint32_t) dest_operand) >> (count - 1) & 1)
|
||||
| (dest_operand >> 20) & FLAG_OVERFLOW;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t sar8(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
if(count < 8)
|
||||
{
|
||||
*last_result = dest_operand << 24 >> count + 24;
|
||||
// of is zero
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW) | (dest_operand >> (count - 1) & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*last_result = dest_operand << 24 >> 31;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW) | (*last_result & 1);
|
||||
}
|
||||
|
||||
*last_op_size = OPSIZE_8;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t sar16(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
if(count < 16)
|
||||
{
|
||||
*last_result = dest_operand << 16 >> count + 16;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW) | (dest_operand >> (count - 1) & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*last_result = dest_operand << 16 >> 31;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW) | (*last_result & 1);
|
||||
}
|
||||
|
||||
*last_op_size = OPSIZE_16;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t sar32(int32_t dest_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand >> count;
|
||||
|
||||
*last_op_size = OPSIZE_32;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~1 & ~FLAG_OVERFLOW) | (((uint32_t) dest_operand) >> (count - 1) & 1);
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shrd16(int32_t dest_operand, int32_t source_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
if(count <= 16)
|
||||
{
|
||||
*last_result = dest_operand >> count | source_operand << (16 - count);
|
||||
*flags = (*flags & ~1) | (dest_operand >> (count - 1) & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*last_result = dest_operand << (32 - count) | source_operand >> (count - 16);
|
||||
*flags = (*flags & ~1) | (source_operand >> (count - 17) & 1);
|
||||
}
|
||||
|
||||
*last_op_size = OPSIZE_16;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~FLAG_OVERFLOW) | ((*last_result ^ dest_operand) >> 4 & FLAG_OVERFLOW);
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shrd32(int32_t dest_operand, int32_t source_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = ((uint32_t) dest_operand) >> count | source_operand << (32 - count);
|
||||
|
||||
*last_op_size = OPSIZE_32;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~1) | (((uint32_t) dest_operand) >> (count - 1) & 1);
|
||||
*flags = (*flags & ~FLAG_OVERFLOW) | ((*last_result ^ dest_operand) >> 20 & FLAG_OVERFLOW);
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shld16(int32_t dest_operand, int32_t source_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
if(count <= 16)
|
||||
{
|
||||
*last_result = dest_operand << count | ((uint32_t) source_operand) >> (16 - count);
|
||||
*flags = (*flags & ~1) | (((uint32_t) dest_operand) >> (16 - count) & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*last_result = dest_operand >> (32 - count) | source_operand << (count - 16);
|
||||
*flags = (*flags & ~1) | (((uint32_t) source_operand) >> (32 - count) & 1);
|
||||
}
|
||||
|
||||
*last_op_size = OPSIZE_16;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~FLAG_OVERFLOW) | ((*flags & 1) ^ (*last_result >> 15 & 1)) << 11;
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
int32_t shld32(int32_t dest_operand, int32_t source_operand, int32_t count)
|
||||
{
|
||||
if(count == 0)
|
||||
{
|
||||
return dest_operand;
|
||||
}
|
||||
|
||||
*last_result = dest_operand << count | ((uint32_t) source_operand) >> (32 - count);
|
||||
|
||||
*last_op_size = OPSIZE_32;
|
||||
*flags_changed = FLAGS_ALL & ~1 & ~FLAG_OVERFLOW;
|
||||
*flags = (*flags & ~1) | (((uint32_t) dest_operand) >> (32 - count) & 1);
|
||||
|
||||
if(count == 1)
|
||||
{
|
||||
*flags = (*flags & ~FLAG_OVERFLOW) | ((*flags & 1) ^ (*last_result >> 31 & 1)) << 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flags &= ~FLAG_OVERFLOW;
|
||||
}
|
||||
|
||||
return *last_result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue