static void __stdcall comb_mask_1_simd(uint8_t* dstp, const uint8_t* srcp, const int dpitch, const int spitch, const int cthresh, const int width, const int height) noexcept { const uint8_t* sc = srcp; const uint8_t* sb = sc + spitch; const uint8_t* sd = sc + spitch; const V cth = set1_i16<V>(static_cast<int16_t>(cthresh)); const V all = cmpeq_i8(cth, cth); constexpr int step = sizeof(V) / 2; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; x += step) { V xb = load_half<V>(sb + x); V xc = load_half<V>(sc + x); V xd = load_half<V>(sd + x); xb = sub_i16(xb, xc); xd = sub_i16(xd, xc); xc = andnot(mulhi(xb, xd), mullo(xb, xd)); xc = cmpgt_u16(xc, cth, all); store_half(dstp + x, xc); } sb = sc; sc = sd; sd += (y < height - 2) ? spitch : -spitch; dstp += dpitch; } }
void program_interrupt (SIM_DESC sd, sim_cpu *cpu, sim_cia cia, SIM_SIGNAL sig) { int status; struct hw *device; static int in_interrupt = 0; #ifdef SIM_CPU_EXCEPTION_TRIGGER SIM_CPU_EXCEPTION_TRIGGER(sd,cpu,cia); #endif /* avoid infinite recursion */ if (in_interrupt) { (*mn10300_callback->printf_filtered) (mn10300_callback, "ERROR: recursion in program_interrupt during software exception dispatch."); } else { in_interrupt = 1; /* copy NMI handler code from dv-mn103cpu.c */ store_word (SP - 4, CPU_PC_GET (cpu)); store_half (SP - 8, PSW); /* Set the SYSEF flag in NMICR by backdoor method. See dv-mn103int.c:write_icr(). This is necessary because software exceptions are not modelled by actually talking to the interrupt controller, so it cannot set its own SYSEF flag. */ if ((NULL != board) && (strcmp(board, BOARD_AM32) == 0)) store_byte (0x34000103, 0x04); } PSW &= ~PSW_IE; SP = SP - 8; CPU_PC_SET (cpu, 0x40000008); in_interrupt = 0; sim_engine_halt(sd, cpu, NULL, cia, sim_stopped, sig); }
static void __stdcall comb_mask_0_simd(uint8_t* dstp, const uint8_t* srcp, const int dpitch, const int spitch, const int cthresh, const int width, const int height) noexcept { const uint8_t* sc = srcp; const uint8_t* sb = sc + spitch; const uint8_t* sa = sb + spitch; const uint8_t* sd = sc + spitch; const uint8_t* se = sd + spitch; int16_t cth16 = static_cast<int16_t>(cthresh); const V cthp = set1_i16<V>(cth16); const V cthn = set1_i16<V>(-cth16); const V cth6 = set1_i16<V>(cth16 * 6); constexpr int step = sizeof(V) / 2; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; x += step) { V xc = load_half<V>(sc + x); V xb = load_half<V>(sb + x); V xd = load_half<V>(sd + x); V d1 = sub_i16(xc, xb); V d2 = sub_i16(xc, xd); V mask0 = or_reg( and_reg(cmpgt_i16(d1, cthp), cmpgt_i16(d2, cthp)), and_reg(cmpgt_i16(cthn, d1), cmpgt_i16(cthn, d2))); d2 = mul3(add_i16(xb, xd)); d1 = add_i16(load_half<V>(sa + x), load_half<V>(se + x)); d1 = add_i16(d1, lshift_i16(xc, 2)); mask0 = and_reg(mask0, cmpgt_i16(absdiff_i16(d1, d2), cth6)); store_half(dstp + x, mask0); } sa = sb; sb = sc; sc = sd; sd = se; se += (y < height - 3) ? spitch : -spitch; dstp += dpitch; } }
static void deliver_mn103cpu_interrupt (struct hw *me, void *data) { struct mn103cpu *controller = hw_data (me); SIM_DESC simulator = hw_system (me); sim_cpu *cpu = STATE_CPU (simulator, 0); if (controller->pending_reset) { controller->pending_reset = 0; /* need to clear all registers et.al! */ HW_TRACE ((me, "Reset!")); hw_abort (me, "Reset!"); } else if (controller->pending_nmi) { controller->pending_nmi = 0; store_word (SP - 4, CPU_PC_GET (cpu)); store_half (SP - 8, PSW); PSW &= ~PSW_IE; SP = SP - 8; CPU_PC_SET (cpu, 0x40000008); HW_TRACE ((me, "nmi pc=0x%08lx psw=0x%04x sp=0x%08lx", (long) CPU_PC_GET (cpu), (unsigned) PSW, (long) SP)); } else if ((controller->pending_level < EXTRACT_PSW_LM) && (PSW & PSW_IE)) { /* Don't clear pending level. Request continues to be pending until the interrupt controller clears/changes it */ store_word (SP - 4, CPU_PC_GET (cpu)); store_half (SP - 8, PSW); PSW &= ~PSW_IE; PSW &= ~PSW_LM; PSW |= INSERT_PSW_LM (controller->pending_level); SP = SP - 8; CPU_PC_SET (cpu, 0x40000000 + controller->interrupt_vector[controller->pending_level]); HW_TRACE ((me, "port-out ack %d", controller->pending_level)); hw_port_event (me, ACK_PORT, controller->pending_level); HW_TRACE ((me, "int level=%d pc=0x%08lx psw=0x%04x sp=0x%08lx", controller->pending_level, (long) CPU_PC_GET (cpu), (unsigned) PSW, (long) SP)); } if (controller->pending_level < 7) /* FIXME */ { /* As long as there is the potential need to deliver an interrupt we keep rescheduling this routine. */ if (controller->pending_handler != NULL) controller->pending_handler = hw_event_queue_schedule (me, 1, deliver_mn103cpu_interrupt, NULL); } else { /* Don't bother re-scheduling the interrupt handler as there is nothing to deliver */ controller->pending_handler = NULL; } }