e132x, looked at subs opcode, nw.

This commit is contained in:
mooglyguy 2017-11-13 19:38:10 +01:00
parent b47c845eda
commit edf05a30a5
3 changed files with 201 additions and 183 deletions

View File

@ -1721,143 +1721,11 @@ offs_t hyperstone_device::disasm_disassemble(std::ostream &stream, offs_t pc, co
/* Opcodes */ /* Opcodes */
void hyperstone_device::hyperstone_subs(regs_decode &decode)
{
if (SRC_IS_SR)
SREG = GET_C;
int64_t tmp = (int64_t)((int32_t)(DREG)) - (int64_t)((int32_t)(SREG));
//#ifdef SETCARRYS
// CHECK_C(tmp);
//#endif
CHECK_VSUB(SREG,DREG,tmp);
int32_t res = (int32_t)(DREG) - (int32_t)(SREG);
SET_DREG(res);
SET_Z(res == 0 ? 1 : 0);
SET_N(SIGN_BIT(res));
m_icount -= m_clock_cycles_1;
if (SR & V_MASK)
{
uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
execute_exception(addr);
}
}
void hyperstone_device::hyperstone_sardi()
{
check_delay_PC();
const uint32_t dst_code = (DST_CODE + GET_FP) % 64;
const uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]);
SR &= ~(C_MASK | Z_MASK | N_MASK);
const uint32_t n = N_VALUE;
if (n)
{
SR |= (val >> (n - 1)) & 1;
const uint64_t sign_bit = val >> 63;
val >>= n;
if (sign_bit)
{
val |= 0xffffffff00000000U << (32 - n);
}
}
m_local_regs[dst_code] = (uint32_t)(val >> 32);
m_local_regs[dstf_code] = (uint32_t)val;
if (val == 0)
SR |= Z_MASK;
SR |= SIGN_TO_N(m_local_regs[dst_code]);
m_icount -= m_clock_cycles_2;
}
void hyperstone_device::hyperstone_shld()
{
check_delay_PC();
uint32_t src_code = (SRC_CODE + GET_FP) % 64;
uint32_t dst_code = (DST_CODE + GET_FP) % 64;
uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
// result undefined if Ls denotes the same register as Ld or Ldf
if (src_code == dst_code || src_code == dstf_code)
{
DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC));
}
else
{
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */
uint32_t low_order = m_local_regs[dstf_code];
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
uint64_t val = concat_64(high_order, low_order);
SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0);
uint32_t tmp = high_order << n;
if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
SET_V(1);
else
SR &= ~V_MASK;
val <<= n;
m_local_regs[dst_code] = extract_64hi(val);
m_local_regs[dstf_code] = extract_64lo(val);
SET_Z(val == 0 ? 1 : 0);
SET_N(SIGN_BIT(high_order));
}
m_icount -= m_clock_cycles_2;
}
void hyperstone_device::hyperstone_shl()
{
check_delay_PC();
uint32_t src_code = SRC_CODE + GET_FP;
uint32_t dst_code = DST_CODE + GET_FP;
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
uint32_t base = m_local_regs[dst_code % 64]; /* registers offset by frame pointer */
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0);
uint32_t ret = base << n;
if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000)))
SET_V(1);
else
SR &= ~V_MASK;
m_local_regs[dst_code % 64] = ret;
SET_Z(ret == 0 ? 1 : 0);
SET_N(SIGN_BIT(ret));
m_icount -= m_clock_cycles_1;
}
void hyperstone_device::hyperstone_trap() void hyperstone_device::hyperstone_trap()
{ {
check_delay_PC(); check_delay_PC();
const uint8_t trapno = (m_op & 0xfc) >> 2; const uint8_t trapno = (m_op & 0xfc) >> 2;
const uint32_t addr = get_trap_addr(trapno); const uint32_t addr = get_trap_addr(trapno);
const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03); const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03);
@ -2079,10 +1947,10 @@ void hyperstone_device::execute_run()
case 0x49: hyperstone_sub_global_local(); break; case 0x49: hyperstone_sub_global_local(); break;
case 0x4a: hyperstone_sub_local_global(); break; case 0x4a: hyperstone_sub_local_global(); break;
case 0x4b: hyperstone_sub_local_local(); break; case 0x4b: hyperstone_sub_local_local(); break;
case 0x4c: op4c(); break; case 0x4c: hyperstone_subs_global_global(); break;
case 0x4d: op4d(); break; case 0x4d: hyperstone_subs_global_local(); break;
case 0x4e: op4e(); break; case 0x4e: hyperstone_subs_local_global(); break;
case 0x4f: op4f(); break; case 0x4f: hyperstone_subs_local_local(); break;
case 0x50: hyperstone_addc_global_global(); break; case 0x50: hyperstone_addc_global_global(); break;
case 0x51: hyperstone_addc_global_local(); break; case 0x51: hyperstone_addc_global_local(); break;
case 0x52: hyperstone_addc_local_global(); break; case 0x52: hyperstone_addc_local_global(); break;

View File

@ -281,7 +281,10 @@ private:
void hyperstone_sub_global_local(); void hyperstone_sub_global_local();
void hyperstone_sub_local_global(); void hyperstone_sub_local_global();
void hyperstone_sub_local_local(); void hyperstone_sub_local_local();
void hyperstone_subs(regs_decode &decode); void hyperstone_subs_global_global();
void hyperstone_subs_global_local();
void hyperstone_subs_local_global();
void hyperstone_subs_local_local();
void hyperstone_addc_global_global(); void hyperstone_addc_global_global();
void hyperstone_addc_global_local(); void hyperstone_addc_global_local();
void hyperstone_addc_local_global(); void hyperstone_addc_local_global();
@ -465,8 +468,6 @@ private:
bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
#endif #endif
void op4c(); void op4d(); void op4e(); void op4f(); // subs
#if 0 #if 0
void generate_op00(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op01(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op00(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op01(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_op02(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op03(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op02(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op03(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);

View File

@ -2078,72 +2078,119 @@ void hyperstone_device::hyperstone_sub_local_local()
m_icount -= m_clock_cycles_1; m_icount -= m_clock_cycles_1;
} }
void hyperstone_device::op4c() void hyperstone_device::hyperstone_subs_global_global()
{ {
regs_decode decode; const uint32_t src_code = SRC_CODE;
check_delay_PC(); const uint32_t dst_code = DST_CODE;
decode.src = SRC_CODE; const int32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : (int32_t)m_global_regs[dst_code];
decode.dst = DST_CODE; const int32_t dreg = (int32_t)m_global_regs[dst_code];
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
decode.src_is_local = 0; SR &= ~(V_MASK | Z_MASK | N_MASK);
SREG = m_global_regs[decode.src];
decode.dst_is_local = 0; //#ifdef SETCARRYS
DREG = m_global_regs[decode.dst]; // CHECK_C(tmp);
//#endif
hyperstone_subs(decode); SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
printf("0x4c, subs global,global\n");
const int32_t res = dreg - sreg;
set_global_register(dst_code, res);
if (res == 0)
SR |= Z_MASK;
SR |= SIGN_TO_N(res);
m_icount -= m_clock_cycles_1;
if (SR & V_MASK)
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
} }
void hyperstone_device::op4d() void hyperstone_device::hyperstone_subs_global_local()
{ {
regs_decode decode; const uint32_t dst_code = DST_CODE;
check_delay_PC(); const int32_t sreg = (int32_t)m_local_regs[(SRC_CODE + GET_FP) & 0x3f];
decode.src = SRC_CODE; const int32_t dreg = (int32_t)m_global_regs[dst_code];
decode.dst = DST_CODE; const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
decode.src_is_local = 1; SR &= ~(V_MASK | Z_MASK | N_MASK);
SREG = m_local_regs[(decode.src + GET_FP) & 0x3f];
decode.dst_is_local = 0; //#ifdef SETCARRYS
DREG = m_global_regs[decode.dst]; // CHECK_C(tmp);
//#endif
hyperstone_subs(decode); SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
printf("0x4d, subs global,local\n");
const int32_t res = dreg - sreg;
set_global_register(dst_code, res);
if (res == 0)
SR |= Z_MASK;
SR |= SIGN_TO_N(res);
m_icount -= m_clock_cycles_1;
if (SR & V_MASK)
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
} }
void hyperstone_device::op4e() void hyperstone_device::hyperstone_subs_local_global()
{ {
regs_decode decode; const uint32_t src_code = SRC_CODE;
check_delay_PC(); const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
decode.src = SRC_CODE; const int32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : (int32_t)m_global_regs[dst_code];
decode.dst = DST_CODE; const int32_t dreg = (int32_t)m_local_regs[dst_code];
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
decode.src_is_local = 0; SR &= ~(V_MASK | Z_MASK | N_MASK);
SREG = m_global_regs[decode.src];
decode.dst_is_local = 1; //#ifdef SETCARRYS
DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; // CHECK_C(tmp);
//#endif
hyperstone_subs(decode); SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
printf("0x4e, subs local,global\n");
const int32_t res = dreg - sreg;
m_local_regs[dst_code] = res;
if (res == 0)
SR |= Z_MASK;
SR |= SIGN_TO_N(res);
m_icount -= m_clock_cycles_1;
if (SR & V_MASK)
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
} }
void hyperstone_device::op4f() void hyperstone_device::hyperstone_subs_local_local()
{ {
regs_decode decode; const uint32_t fp = GET_FP;
check_delay_PC(); const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
decode.src = SRC_CODE; const int32_t sreg = (int32_t)m_local_regs[(SRC_CODE + fp) & 0x3f];
decode.dst = DST_CODE; const int32_t dreg = (int32_t)m_local_regs[dst_code];
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
decode.src_is_local = 1; SR &= ~(V_MASK | Z_MASK | N_MASK);
SREG = m_local_regs[(decode.src + GET_FP) & 0x3f];
decode.dst_is_local = 1; //#ifdef SETCARRYS
DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */ // CHECK_C(tmp);
//#endif
hyperstone_subs(decode); SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
printf("0x4f, subs local,local\n");
const int32_t res = dreg - sreg;
m_local_regs[dst_code] = res;
if (res == 0)
SR |= Z_MASK;
SR |= SIGN_TO_N(res);
m_icount -= m_clock_cycles_1;
if (SR & V_MASK)
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
} }
@ -3512,6 +3559,41 @@ void hyperstone_device::hyperstone_shr()
m_icount -= m_clock_cycles_1; m_icount -= m_clock_cycles_1;
} }
void hyperstone_device::hyperstone_sardi()
{
check_delay_PC();
const uint32_t dst_code = (DST_CODE + GET_FP) % 64;
const uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]);
SR &= ~(C_MASK | Z_MASK | N_MASK);
const uint32_t n = N_VALUE;
if (n)
{
SR |= (val >> (n - 1)) & 1;
const uint64_t sign_bit = val >> 63;
val >>= n;
if (sign_bit)
{
val |= 0xffffffff00000000U << (32 - n);
}
}
m_local_regs[dst_code] = (uint32_t)(val >> 32);
m_local_regs[dstf_code] = (uint32_t)val;
if (val == 0)
SR |= Z_MASK;
SR |= SIGN_TO_N(m_local_regs[dst_code]);
m_icount -= m_clock_cycles_2;
}
void hyperstone_device::hyperstone_sard() void hyperstone_device::hyperstone_sard()
{ {
check_delay_PC(); check_delay_PC();
@ -3629,6 +3711,73 @@ void hyperstone_device::hyperstone_shldi()
m_icount -= m_clock_cycles_2; m_icount -= m_clock_cycles_2;
} }
void hyperstone_device::hyperstone_shld()
{
check_delay_PC();
uint32_t src_code = (SRC_CODE + GET_FP) % 64;
uint32_t dst_code = (DST_CODE + GET_FP) % 64;
uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
// result undefined if Ls denotes the same register as Ld or Ldf
if (src_code == dst_code || src_code == dstf_code)
{
DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC));
}
else
{
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */
uint32_t low_order = m_local_regs[dstf_code];
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
uint64_t val = concat_64(high_order, low_order);
SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0);
uint32_t tmp = high_order << n;
if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
SET_V(1);
else
SR &= ~V_MASK;
val <<= n;
m_local_regs[dst_code] = extract_64hi(val);
m_local_regs[dstf_code] = extract_64lo(val);
SET_Z(val == 0 ? 1 : 0);
SET_N(SIGN_BIT(high_order));
}
m_icount -= m_clock_cycles_2;
}
void hyperstone_device::hyperstone_shl()
{
check_delay_PC();
uint32_t src_code = SRC_CODE + GET_FP;
uint32_t dst_code = DST_CODE + GET_FP;
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
uint32_t base = m_local_regs[dst_code % 64]; /* registers offset by frame pointer */
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0);
uint32_t ret = base << n;
if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000)))
SET_V(1);
else
SR &= ~V_MASK;
m_local_regs[dst_code % 64] = ret;
SET_Z(ret == 0 ? 1 : 0);
SET_N(SIGN_BIT(ret));
m_icount -= m_clock_cycles_1;
}
void hyperstone_device::hyperstone_testlz() void hyperstone_device::hyperstone_testlz()
{ {
check_delay_PC(); check_delay_PC();