port shift functions etc. from arith.js

This commit is contained in:
Awal Garg 2017-07-27 16:46:24 +05:30 committed by Fabian
parent c866462bd6
commit 3140cce77f
3 changed files with 280 additions and 15 deletions

View file

@ -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); },

View file

@ -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'];

View file

@ -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;
}