Convert m68k target to TCG.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4565 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
3979144c49
commit
e1f3808e03
2
configure
vendored
2
configure
vendored
@ -1237,10 +1237,8 @@ case "$target_cpu" in
|
||||
;;
|
||||
m68k)
|
||||
echo "TARGET_ARCH=m68k" >> $config_mak
|
||||
echo "CONFIG_DYNGEN_OP=yes" >> $config_mak
|
||||
echo "#define TARGET_ARCH \"m68k\"" >> $config_h
|
||||
echo "#define TARGET_M68K 1" >> $config_h
|
||||
echo "#define CONFIG_DYNGEN_OP 1" >> $config_h
|
||||
bflt="yes"
|
||||
;;
|
||||
mips|mipsel)
|
||||
|
@ -108,7 +108,7 @@ typedef struct CPUM68KState {
|
||||
int exception_index;
|
||||
int interrupt_request;
|
||||
int user_mode_only;
|
||||
int halted;
|
||||
uint32_t halted;
|
||||
|
||||
int pending_vector;
|
||||
int pending_level;
|
||||
@ -120,6 +120,7 @@ typedef struct CPUM68KState {
|
||||
uint32_t features;
|
||||
} CPUM68KState;
|
||||
|
||||
void m68k_tcg_init(void);
|
||||
CPUM68KState *cpu_m68k_init(const char *cpu_model);
|
||||
int cpu_m68k_exec(CPUM68KState *s);
|
||||
void cpu_m68k_close(CPUM68KState *s);
|
||||
@ -141,9 +142,7 @@ enum {
|
||||
CC_OP_CMPW, /* CC_DEST = result, CC_SRC = source */
|
||||
CC_OP_ADDX, /* CC_DEST = result, CC_SRC = source */
|
||||
CC_OP_SUBX, /* CC_DEST = result, CC_SRC = source */
|
||||
CC_OP_SHL, /* CC_DEST = source, CC_SRC = shift */
|
||||
CC_OP_SHR, /* CC_DEST = source, CC_SRC = shift */
|
||||
CC_OP_SAR, /* CC_DEST = source, CC_SRC = shift */
|
||||
CC_OP_SHIFT, /* CC_DEST = result, CC_SRC = carry */
|
||||
};
|
||||
|
||||
#define CCF_C 0x01
|
||||
|
@ -45,8 +45,6 @@ int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
#endif
|
||||
|
||||
void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op);
|
||||
float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1);
|
||||
void helper_movec(CPUM68KState *env, int reg, uint32_t val);
|
||||
|
||||
void cpu_loop_exit(void);
|
||||
|
||||
|
@ -27,6 +27,10 @@
|
||||
#include "exec-all.h"
|
||||
#include "qemu-common.h"
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
#define SIGNBIT (1u << 31)
|
||||
|
||||
enum m68k_cpuid {
|
||||
M68K_CPUID_M5206,
|
||||
M68K_CPUID_M5208,
|
||||
@ -121,11 +125,16 @@ void cpu_reset(CPUM68KState *env)
|
||||
CPUM68KState *cpu_m68k_init(const char *cpu_model)
|
||||
{
|
||||
CPUM68KState *env;
|
||||
static int inited;
|
||||
|
||||
env = malloc(sizeof(CPUM68KState));
|
||||
if (!env)
|
||||
return NULL;
|
||||
cpu_exec_init(env);
|
||||
if (!inited) {
|
||||
inited = 1;
|
||||
m68k_tcg_init();
|
||||
}
|
||||
|
||||
env->cpu_model_str = cpu_model;
|
||||
|
||||
@ -211,34 +220,9 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
|
||||
if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
|
||||
flags |= CCF_V;
|
||||
break;
|
||||
case CC_OP_SHL:
|
||||
if (src >= 32) {
|
||||
SET_NZ(0);
|
||||
} else {
|
||||
tmp = dest << src;
|
||||
SET_NZ(tmp);
|
||||
}
|
||||
if (src && src <= 32 && (dest & (1 << (32 - src))))
|
||||
flags |= CCF_C;
|
||||
break;
|
||||
case CC_OP_SHR:
|
||||
if (src >= 32) {
|
||||
SET_NZ(0);
|
||||
} else {
|
||||
tmp = dest >> src;
|
||||
SET_NZ(tmp);
|
||||
}
|
||||
if (src && src <= 32 && ((dest >> (src - 1)) & 1))
|
||||
flags |= CCF_C;
|
||||
break;
|
||||
case CC_OP_SAR:
|
||||
if (src >= 32) {
|
||||
SET_NZ(-1);
|
||||
} else {
|
||||
tmp = (int32_t)dest >> src;
|
||||
SET_NZ(tmp);
|
||||
}
|
||||
if (src && src <= 32 && (((int32_t)dest >> (src - 1)) & 1))
|
||||
case CC_OP_SHIFT:
|
||||
SET_NZ(dest);
|
||||
if (src)
|
||||
flags |= CCF_C;
|
||||
break;
|
||||
default:
|
||||
@ -248,25 +232,7 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
|
||||
env->cc_dest = flags;
|
||||
}
|
||||
|
||||
float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1)
|
||||
{
|
||||
/* ??? This may incorrectly raise exceptions. */
|
||||
/* ??? Should flush denormals to zero. */
|
||||
float64 res;
|
||||
res = float64_sub(src0, src1, &env->fp_status);
|
||||
if (float64_is_nan(res)) {
|
||||
/* +/-inf compares equal against itself, but sub returns nan. */
|
||||
if (!float64_is_nan(src0)
|
||||
&& !float64_is_nan(src1)) {
|
||||
res = float64_zero;
|
||||
if (float64_lt_quiet(src0, res, &env->fp_status))
|
||||
res = float64_chs(res);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void helper_movec(CPUM68KState *env, int reg, uint32_t val)
|
||||
void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
|
||||
{
|
||||
switch (reg) {
|
||||
case 0x02: /* CACR */
|
||||
@ -286,7 +252,7 @@ void helper_movec(CPUM68KState *env, int reg, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_set_macsr(CPUM68KState *env, uint32_t val)
|
||||
void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
|
||||
{
|
||||
uint32_t acc;
|
||||
int8_t exthigh;
|
||||
@ -376,3 +342,541 @@ void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint32_t HELPER(bitrev)(uint32_t x)
|
||||
{
|
||||
x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
|
||||
x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
|
||||
x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
|
||||
return bswap32(x);
|
||||
}
|
||||
|
||||
uint32_t HELPER(ff1)(uint32_t x)
|
||||
{
|
||||
int n;
|
||||
for (n = 32; x; n--)
|
||||
x >>= 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
|
||||
{
|
||||
/* The result has the opposite sign to the original value. */
|
||||
if (ccr & CCF_V)
|
||||
val = (((int32_t)val) >> 31) ^ SIGNBIT;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t HELPER(subx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t res;
|
||||
uint32_t old_flags;
|
||||
|
||||
old_flags = env->cc_dest;
|
||||
if (env->cc_x) {
|
||||
env->cc_x = (op1 <= op2);
|
||||
env->cc_op = CC_OP_SUBX;
|
||||
res = op1 - (op2 + 1);
|
||||
} else {
|
||||
env->cc_x = (op1 < op2);
|
||||
env->cc_op = CC_OP_SUB;
|
||||
res = op1 - op2;
|
||||
}
|
||||
env->cc_dest = res;
|
||||
env->cc_src = op2;
|
||||
cpu_m68k_flush_flags(env, env->cc_op);
|
||||
/* !Z is sticky. */
|
||||
env->cc_dest &= (old_flags | ~CCF_Z);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t HELPER(addx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t res;
|
||||
uint32_t old_flags;
|
||||
|
||||
old_flags = env->cc_dest;
|
||||
if (env->cc_x) {
|
||||
res = op1 + op2 + 1;
|
||||
env->cc_x = (res <= op2);
|
||||
env->cc_op = CC_OP_ADDX;
|
||||
} else {
|
||||
res = op1 + op2;
|
||||
env->cc_x = (res < op2);
|
||||
env->cc_op = CC_OP_ADD;
|
||||
}
|
||||
env->cc_dest = res;
|
||||
env->cc_src = op2;
|
||||
cpu_m68k_flush_flags(env, env->cc_op);
|
||||
/* !Z is sticky. */
|
||||
env->cc_dest &= (old_flags | ~CCF_Z);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
uint32_t HELPER(btest)(uint32_t x)
|
||||
{
|
||||
return x != 0;
|
||||
}
|
||||
|
||||
void HELPER(set_sr)(CPUState *env, uint32_t val)
|
||||
{
|
||||
env->sr = val & 0xffff;
|
||||
m68k_switch_sp(env);
|
||||
}
|
||||
|
||||
uint32_t HELPER(shl_cc)(CPUState *env, uint32_t val, uint32_t shift)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t cf;
|
||||
|
||||
shift &= 63;
|
||||
if (shift == 0) {
|
||||
result = val;
|
||||
cf = env->cc_src & CCF_C;
|
||||
} else if (shift < 32) {
|
||||
result = val << shift;
|
||||
cf = (val >> (32 - shift)) & 1;
|
||||
} else if (shift == 32) {
|
||||
result = 0;
|
||||
cf = val & 1;
|
||||
} else /* shift > 32 */ {
|
||||
result = 0;
|
||||
cf = 0;
|
||||
}
|
||||
env->cc_src = cf;
|
||||
env->cc_x = (cf != 0);
|
||||
env->cc_dest = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t HELPER(shr_cc)(CPUState *env, uint32_t val, uint32_t shift)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t cf;
|
||||
|
||||
shift &= 63;
|
||||
if (shift == 0) {
|
||||
result = val;
|
||||
cf = env->cc_src & CCF_C;
|
||||
} else if (shift < 32) {
|
||||
result = val >> shift;
|
||||
cf = (val >> (shift - 1)) & 1;
|
||||
} else if (shift == 32) {
|
||||
result = 0;
|
||||
cf = val >> 31;
|
||||
} else /* shift > 32 */ {
|
||||
result = 0;
|
||||
cf = 0;
|
||||
}
|
||||
env->cc_src = cf;
|
||||
env->cc_x = (cf != 0);
|
||||
env->cc_dest = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t HELPER(sar_cc)(CPUState *env, uint32_t val, uint32_t shift)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t cf;
|
||||
|
||||
shift &= 63;
|
||||
if (shift == 0) {
|
||||
result = val;
|
||||
cf = (env->cc_src & CCF_C) != 0;
|
||||
} else if (shift < 32) {
|
||||
result = (int32_t)val >> shift;
|
||||
cf = (val >> (shift - 1)) & 1;
|
||||
} else /* shift >= 32 */ {
|
||||
result = (int32_t)val >> 31;
|
||||
cf = val >> 31;
|
||||
}
|
||||
env->cc_src = cf;
|
||||
env->cc_x = cf;
|
||||
env->cc_dest = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FPU helpers. */
|
||||
uint32_t HELPER(f64_to_i32)(CPUState *env, float64 val)
|
||||
{
|
||||
return float64_to_int32(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(f64_to_f32)(CPUState *env, float64 val)
|
||||
{
|
||||
return float64_to_float32(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(i32_to_f64)(CPUState *env, uint32_t val)
|
||||
{
|
||||
return int32_to_float64(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(f32_to_f64)(CPUState *env, float32 val)
|
||||
{
|
||||
return float32_to_float64(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(iround_f64)(CPUState *env, float64 val)
|
||||
{
|
||||
return float64_round_to_int(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(itrunc_f64)(CPUState *env, float64 val)
|
||||
{
|
||||
return float64_trunc_to_int(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(sqrt_f64)(CPUState *env, float64 val)
|
||||
{
|
||||
return float64_sqrt(val, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(abs_f64)(float64 val)
|
||||
{
|
||||
return float64_abs(val);
|
||||
}
|
||||
|
||||
float64 HELPER(chs_f64)(float64 val)
|
||||
{
|
||||
return float64_chs(val);
|
||||
}
|
||||
|
||||
float64 HELPER(add_f64)(CPUState *env, float64 a, float64 b)
|
||||
{
|
||||
return float64_add(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(sub_f64)(CPUState *env, float64 a, float64 b)
|
||||
{
|
||||
return float64_sub(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(mul_f64)(CPUState *env, float64 a, float64 b)
|
||||
{
|
||||
return float64_mul(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(div_f64)(CPUState *env, float64 a, float64 b)
|
||||
{
|
||||
return float64_div(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float64 HELPER(sub_cmp_f64)(CPUState *env, float64 a, float64 b)
|
||||
{
|
||||
/* ??? This may incorrectly raise exceptions. */
|
||||
/* ??? Should flush denormals to zero. */
|
||||
float64 res;
|
||||
res = float64_sub(a, b, &env->fp_status);
|
||||
if (float64_is_nan(res)) {
|
||||
/* +/-inf compares equal against itself, but sub returns nan. */
|
||||
if (!float64_is_nan(a)
|
||||
&& !float64_is_nan(b)) {
|
||||
res = float64_zero;
|
||||
if (float64_lt_quiet(a, res, &env->fp_status))
|
||||
res = float64_chs(res);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t HELPER(compare_f64)(CPUState *env, float64 val)
|
||||
{
|
||||
return float64_compare_quiet(val, float64_zero, &env->fp_status);
|
||||
}
|
||||
|
||||
/* MAC unit. */
|
||||
/* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
|
||||
take values, others take register numbers and manipulate the contents
|
||||
in-place. */
|
||||
void HELPER(mac_move)(CPUState *env, uint32_t dest, uint32_t src)
|
||||
{
|
||||
uint32_t mask;
|
||||
env->macc[dest] = env->macc[src];
|
||||
mask = MACSR_PAV0 << dest;
|
||||
if (env->macsr & (MACSR_PAV0 << src))
|
||||
env->macsr |= mask;
|
||||
else
|
||||
env->macsr &= ~mask;
|
||||
}
|
||||
|
||||
uint64_t HELPER(macmuls)(CPUState *env, uint32_t op1, uint32_t op2)
|
||||
{
|
||||
int64_t product;
|
||||
int64_t res;
|
||||
|
||||
product = (uint64_t)op1 * op2;
|
||||
res = (product << 24) >> 24;
|
||||
if (res != product) {
|
||||
env->macsr |= MACSR_V;
|
||||
if (env->macsr & MACSR_OMC) {
|
||||
/* Make sure the accumulate operation overflows. */
|
||||
if (product < 0)
|
||||
res = ~(1ll << 50);
|
||||
else
|
||||
res = 1ll << 50;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint64_t HELPER(macmulu)(CPUState *env, uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint64_t product;
|
||||
|
||||
product = (uint64_t)op1 * op2;
|
||||
if (product & (0xffffffull << 40)) {
|
||||
env->macsr |= MACSR_V;
|
||||
if (env->macsr & MACSR_OMC) {
|
||||
/* Make sure the accumulate operation overflows. */
|
||||
product = 1ll << 50;
|
||||
} else {
|
||||
product &= ((1ull << 40) - 1);
|
||||
}
|
||||
}
|
||||
return product;
|
||||
}
|
||||
|
||||
uint64_t HELPER(macmulf)(CPUState *env, uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint64_t product;
|
||||
uint32_t remainder;
|
||||
|
||||
product = (uint64_t)op1 * op2;
|
||||
if (env->macsr & MACSR_RT) {
|
||||
remainder = product & 0xffffff;
|
||||
product >>= 24;
|
||||
if (remainder > 0x800000)
|
||||
product++;
|
||||
else if (remainder == 0x800000)
|
||||
product += (product & 1);
|
||||
} else {
|
||||
product >>= 24;
|
||||
}
|
||||
return product;
|
||||
}
|
||||
|
||||
void HELPER(macsats)(CPUState *env, uint32_t acc)
|
||||
{
|
||||
int64_t tmp;
|
||||
int64_t result;
|
||||
tmp = env->macc[acc];
|
||||
result = ((tmp << 16) >> 16);
|
||||
if (result != tmp) {
|
||||
env->macsr |= MACSR_V;
|
||||
}
|
||||
if (env->macsr & MACSR_V) {
|
||||
env->macsr |= MACSR_PAV0 << acc;
|
||||
if (env->macsr & MACSR_OMC) {
|
||||
/* The result is saturated to 32 bits, despite overflow occuring
|
||||
at 48 bits. Seems weird, but that's what the hardware docs
|
||||
say. */
|
||||
result = (result >> 63) ^ 0x7fffffff;
|
||||
}
|
||||
}
|
||||
env->macc[acc] = result;
|
||||
}
|
||||
|
||||
void HELPER(macsatu)(CPUState *env, uint32_t acc)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
val = env->macc[acc];
|
||||
if (val & (0xffffull << 48)) {
|
||||
env->macsr |= MACSR_V;
|
||||
}
|
||||
if (env->macsr & MACSR_V) {
|
||||
env->macsr |= MACSR_PAV0 << acc;
|
||||
if (env->macsr & MACSR_OMC) {
|
||||
if (val > (1ull << 53))
|
||||
val = 0;
|
||||
else
|
||||
val = (1ull << 48) - 1;
|
||||
} else {
|
||||
val &= ((1ull << 48) - 1);
|
||||
}
|
||||
}
|
||||
env->macc[acc] = val;
|
||||
}
|
||||
|
||||
void HELPER(macsatf)(CPUState *env, uint32_t acc)
|
||||
{
|
||||
int64_t sum;
|
||||
int64_t result;
|
||||
|
||||
sum = env->macc[acc];
|
||||
result = (sum << 16) >> 16;
|
||||
if (result != sum) {
|
||||
env->macsr |= MACSR_V;
|
||||
}
|
||||
if (env->macsr & MACSR_V) {
|
||||
env->macsr |= MACSR_PAV0 << acc;
|
||||
if (env->macsr & MACSR_OMC) {
|
||||
result = (result >> 63) ^ 0x7fffffffffffll;
|
||||
}
|
||||
}
|
||||
env->macc[acc] = result;
|
||||
}
|
||||
|
||||
void HELPER(mac_set_flags)(CPUState *env, uint32_t acc)
|
||||
{
|
||||
uint64_t val;
|
||||
val = env->macc[acc];
|
||||
if (val == 0)
|
||||
env->macsr |= MACSR_Z;
|
||||
else if (val & (1ull << 47));
|
||||
env->macsr |= MACSR_N;
|
||||
if (env->macsr & (MACSR_PAV0 << acc)) {
|
||||
env->macsr |= MACSR_V;
|
||||
}
|
||||
if (env->macsr & MACSR_FI) {
|
||||
val = ((int64_t)val) >> 40;
|
||||
if (val != 0 && val != -1)
|
||||
env->macsr |= MACSR_EV;
|
||||
} else if (env->macsr & MACSR_SU) {
|
||||
val = ((int64_t)val) >> 32;
|
||||
if (val != 0 && val != -1)
|
||||
env->macsr |= MACSR_EV;
|
||||
} else {
|
||||
if ((val >> 32) != 0)
|
||||
env->macsr |= MACSR_EV;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(flush_flags)(CPUState *env, uint32_t cc_op)
|
||||
{
|
||||
cpu_m68k_flush_flags(env, cc_op);
|
||||
}
|
||||
|
||||
uint32_t HELPER(get_macf)(CPUState *env, uint64_t val)
|
||||
{
|
||||
int rem;
|
||||
uint32_t result;
|
||||
|
||||
if (env->macsr & MACSR_SU) {
|
||||
/* 16-bit rounding. */
|
||||
rem = val & 0xffffff;
|
||||
val = (val >> 24) & 0xffffu;
|
||||
if (rem > 0x800000)
|
||||
val++;
|
||||
else if (rem == 0x800000)
|
||||
val += (val & 1);
|
||||
} else if (env->macsr & MACSR_RT) {
|
||||
/* 32-bit rounding. */
|
||||
rem = val & 0xff;
|
||||
val >>= 8;
|
||||
if (rem > 0x80)
|
||||
val++;
|
||||
else if (rem == 0x80)
|
||||
val += (val & 1);
|
||||
} else {
|
||||
/* No rounding. */
|
||||
val >>= 8;
|
||||
}
|
||||
if (env->macsr & MACSR_OMC) {
|
||||
/* Saturate. */
|
||||
if (env->macsr & MACSR_SU) {
|
||||
if (val != (uint16_t) val) {
|
||||
result = ((val >> 63) ^ 0x7fff) & 0xffff;
|
||||
} else {
|
||||
result = val & 0xffff;
|
||||
}
|
||||
} else {
|
||||
if (val != (uint32_t)val) {
|
||||
result = ((uint32_t)(val >> 63) & 0x7fffffff);
|
||||
} else {
|
||||
result = (uint32_t)val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No saturation. */
|
||||
if (env->macsr & MACSR_SU) {
|
||||
result = val & 0xffff;
|
||||
} else {
|
||||
result = (uint32_t)val;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t HELPER(get_macs)(uint64_t val)
|
||||
{
|
||||
if (val == (int32_t)val) {
|
||||
return (int32_t)val;
|
||||
} else {
|
||||
return (val >> 61) ^ ~SIGNBIT;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HELPER(get_macu)(uint64_t val)
|
||||
{
|
||||
if ((val >> 32) == 0) {
|
||||
return (uint32_t)val;
|
||||
} else {
|
||||
return 0xffffffffu;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HELPER(get_mac_extf)(CPUState *env, uint32_t acc)
|
||||
{
|
||||
uint32_t val;
|
||||
val = env->macc[acc] & 0x00ff;
|
||||
val = (env->macc[acc] >> 32) & 0xff00;
|
||||
val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
|
||||
val |= (env->macc[acc + 1] >> 16) & 0xff000000;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t HELPER(get_mac_exti)(CPUState *env, uint32_t acc)
|
||||
{
|
||||
uint32_t val;
|
||||
val = (env->macc[acc] >> 32) & 0xffff;
|
||||
val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
|
||||
return val;
|
||||
}
|
||||
|
||||
void HELPER(set_mac_extf)(CPUState *env, uint32_t val, uint32_t acc)
|
||||
{
|
||||
int64_t res;
|
||||
int32_t tmp;
|
||||
res = env->macc[acc] & 0xffffffff00ull;
|
||||
tmp = (int16_t)(val & 0xff00);
|
||||
res |= ((int64_t)tmp) << 32;
|
||||
res |= val & 0xff;
|
||||
env->macc[acc] = res;
|
||||
res = env->macc[acc + 1] & 0xffffffff00ull;
|
||||
tmp = (val & 0xff000000);
|
||||
res |= ((int64_t)tmp) << 16;
|
||||
res |= (val >> 16) & 0xff;
|
||||
env->macc[acc + 1] = res;
|
||||
}
|
||||
|
||||
void HELPER(set_mac_exts)(CPUState *env, uint32_t val, uint32_t acc)
|
||||
{
|
||||
int64_t res;
|
||||
int32_t tmp;
|
||||
res = (uint32_t)env->macc[acc];
|
||||
tmp = (int16_t)val;
|
||||
res |= ((int64_t)tmp) << 32;
|
||||
env->macc[acc] = res;
|
||||
res = (uint32_t)env->macc[acc + 1];
|
||||
tmp = val & 0xffff0000;
|
||||
res |= (int64_t)tmp << 16;
|
||||
env->macc[acc + 1] = res;
|
||||
}
|
||||
|
||||
void HELPER(set_mac_extu)(CPUState *env, uint32_t val, uint32_t acc)
|
||||
{
|
||||
uint64_t res;
|
||||
res = (uint32_t)env->macc[acc];
|
||||
res |= ((uint64_t)(val & 0xffff)) << 32;
|
||||
env->macc[acc] = res;
|
||||
res = (uint32_t)env->macc[acc + 1];
|
||||
res |= (uint64_t)(val & 0xffff0000) << 16;
|
||||
env->macc[acc + 1] = res;
|
||||
}
|
||||
|
138
target-m68k/helpers.h
Normal file
138
target-m68k/helpers.h
Normal file
@ -0,0 +1,138 @@
|
||||
#ifndef DEF_HELPER
|
||||
#define DEF_HELPER(name, ret, args) ret glue(helper_,name) args;
|
||||
#endif
|
||||
|
||||
#ifdef GEN_HELPER
|
||||
#define DEF_HELPER_0_0(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(void) \
|
||||
{ \
|
||||
tcg_gen_helper_0_0(helper_##name); \
|
||||
}
|
||||
#define DEF_HELPER_0_1(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv arg1) \
|
||||
{ \
|
||||
tcg_gen_helper_0_1(helper_##name, arg1); \
|
||||
}
|
||||
#define DEF_HELPER_0_2(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv arg1, TCGv arg2) \
|
||||
{ \
|
||||
tcg_gen_helper_0_2(helper_##name, arg1, arg2); \
|
||||
}
|
||||
#define DEF_HELPER_0_3(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name( \
|
||||
TCGv arg1, TCGv arg2, TCGv arg3) \
|
||||
{ \
|
||||
tcg_gen_helper_0_3(helper_##name, arg1, arg2, arg3); \
|
||||
}
|
||||
#define DEF_HELPER_1_0(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret) \
|
||||
{ \
|
||||
tcg_gen_helper_1_0(helper_##name, ret); \
|
||||
}
|
||||
#define DEF_HELPER_1_1(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, TCGv arg1) \
|
||||
{ \
|
||||
tcg_gen_helper_1_1(helper_##name, ret, arg1); \
|
||||
}
|
||||
#define DEF_HELPER_1_2(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, TCGv arg1, TCGv arg2) \
|
||||
{ \
|
||||
tcg_gen_helper_1_2(helper_##name, ret, arg1, arg2); \
|
||||
}
|
||||
#define DEF_HELPER_1_3(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, \
|
||||
TCGv arg1, TCGv arg2, TCGv arg3) \
|
||||
{ \
|
||||
tcg_gen_helper_1_3(helper_##name, ret, arg1, arg2, arg3); \
|
||||
}
|
||||
#define DEF_HELPER_1_4(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, \
|
||||
TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) \
|
||||
{ \
|
||||
tcg_gen_helper_1_4(helper_##name, ret, arg1, arg2, arg3, arg4); \
|
||||
}
|
||||
#else /* !GEN_HELPER */
|
||||
#define DEF_HELPER_0_0 DEF_HELPER
|
||||
#define DEF_HELPER_0_1 DEF_HELPER
|
||||
#define DEF_HELPER_0_2 DEF_HELPER
|
||||
#define DEF_HELPER_0_3 DEF_HELPER
|
||||
#define DEF_HELPER_1_0 DEF_HELPER
|
||||
#define DEF_HELPER_1_1 DEF_HELPER
|
||||
#define DEF_HELPER_1_2 DEF_HELPER
|
||||
#define DEF_HELPER_1_3 DEF_HELPER
|
||||
#define DEF_HELPER_1_4 DEF_HELPER
|
||||
#define HELPER(x) glue(helper_,x)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_1_1(bitrev, uint32_t, (uint32_t))
|
||||
DEF_HELPER_1_1(ff1, uint32_t, (uint32_t))
|
||||
DEF_HELPER_1_2(sats, uint32_t, (uint32_t, uint32_t))
|
||||
DEF_HELPER_0_2(divu, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(divs, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_3(addx_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(subx_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(shl_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(shr_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(sar_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_2(xflag_lt, uint32_t, (uint32_t, uint32_t))
|
||||
DEF_HELPER_0_2(set_sr, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_3(movec, void, (CPUState *, uint32_t, uint32_t))
|
||||
|
||||
DEF_HELPER_1_2(f64_to_i32, float32, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(f64_to_f32, float32, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(i32_to_f64, float64, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_2(f32_to_f64, float64, (CPUState *, float32))
|
||||
DEF_HELPER_1_2(iround_f64, float64, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(itrunc_f64, float64, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(sqrt_f64, float64, (CPUState *, float64))
|
||||
DEF_HELPER_1_1(abs_f64, float64, (float64))
|
||||
DEF_HELPER_1_1(chs_f64, float64, (float64))
|
||||
DEF_HELPER_1_3(add_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(sub_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(mul_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(div_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(sub_cmp_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_2(compare_f64, uint32_t, (CPUState *, float64))
|
||||
|
||||
DEF_HELPER_0_3(mac_move, void, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(macmulf, uint64_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(macmuls, uint64_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(macmulu, uint64_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_0_2(macsats, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(macsatu, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(macsatf, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(mac_set_flags, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(set_macsr, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_2(get_macf, uint32_t, (CPUState *, uint64_t))
|
||||
DEF_HELPER_1_1(get_macs, uint32_t, (uint64_t))
|
||||
DEF_HELPER_1_1(get_macu, uint32_t, (uint64_t))
|
||||
DEF_HELPER_1_2(get_mac_extf, uint32_t, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_2(get_mac_exti, uint32_t, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_3(set_mac_extf, void, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_0_3(set_mac_exts, void, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_0_3(set_mac_extu, void, (CPUState *, uint32_t, uint32_t))
|
||||
|
||||
DEF_HELPER_0_2(flush_flags, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_1(raise_exception, void, (uint32_t))
|
||||
|
||||
#undef DEF_HELPER
|
||||
#undef DEF_HELPER_0_0
|
||||
#undef DEF_HELPER_0_1
|
||||
#undef DEF_HELPER_0_2
|
||||
#undef DEF_HELPER_0_3
|
||||
#undef DEF_HELPER_1_0
|
||||
#undef DEF_HELPER_1_1
|
||||
#undef DEF_HELPER_1_2
|
||||
#undef DEF_HELPER_1_3
|
||||
#undef DEF_HELPER_1_4
|
||||
#undef GEN_HELPER
|
||||
#undef DEF_HELPER
|
@ -1,130 +0,0 @@
|
||||
/* Various hacks to make code written for a dynamic code generator work
|
||||
with regular QEMU. */
|
||||
|
||||
static int free_qreg;
|
||||
|
||||
#define QMODE_I32 1
|
||||
#define QMODE_F32 1
|
||||
#define QMODE_F64 2
|
||||
|
||||
static inline int gen_new_qreg(int mode)
|
||||
{
|
||||
int qreg;
|
||||
|
||||
qreg = free_qreg;
|
||||
free_qreg += mode;
|
||||
if (free_qreg > MAX_QREGS) {
|
||||
fprintf(stderr, "qreg overflow\n");
|
||||
abort();
|
||||
}
|
||||
return qreg + TARGET_NUM_QREGS;
|
||||
}
|
||||
|
||||
static inline int gen_im32(uint32_t i)
|
||||
{
|
||||
int qreg = gen_new_qreg(QMODE_I32);
|
||||
gen_op_mov32_im(qreg, i);
|
||||
return qreg;
|
||||
}
|
||||
|
||||
static inline void gen_op_ldf32_raw(int dest, int addr)
|
||||
{
|
||||
gen_op_ld32_raw(dest, addr);
|
||||
}
|
||||
|
||||
static inline void gen_op_stf32_raw(int addr, int dest)
|
||||
{
|
||||
gen_op_st32_raw(addr, dest);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static inline void gen_op_ldf32_user(int dest, int addr)
|
||||
{
|
||||
gen_op_ld32_user(dest, addr);
|
||||
}
|
||||
|
||||
static inline void gen_op_stf32_user(int addr, int dest)
|
||||
{
|
||||
gen_op_st32_user(addr, dest);
|
||||
}
|
||||
|
||||
static inline void gen_op_ldf32_kernel(int dest, int addr)
|
||||
{
|
||||
gen_op_ld32_kernel(dest, addr);
|
||||
}
|
||||
|
||||
static inline void gen_op_stf32_kernel(int addr, int dest)
|
||||
{
|
||||
gen_op_st32_kernel(addr, dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void gen_op_pack_32_f32(int dest, int src)
|
||||
{
|
||||
gen_op_mov32(dest, src);
|
||||
}
|
||||
|
||||
static inline void gen_op_pack_f32_32(int dest, int src)
|
||||
{
|
||||
gen_op_mov32(dest, src);
|
||||
}
|
||||
|
||||
static inline void gen_op_flags_set(void)
|
||||
{
|
||||
/* Dummy op. */
|
||||
}
|
||||
|
||||
static inline void gen_op_shl_im_cc(int val, int shift)
|
||||
{
|
||||
gen_op_shl_cc(val, gen_im32(shift));
|
||||
}
|
||||
|
||||
static inline void gen_op_shr_im_cc(int val, int shift)
|
||||
{
|
||||
gen_op_shr_cc(val, gen_im32(shift));
|
||||
}
|
||||
|
||||
static inline void gen_op_sar_im_cc(int val, int shift)
|
||||
{
|
||||
gen_op_sar_cc(val, gen_im32(shift));
|
||||
}
|
||||
|
||||
#ifdef USE_DIRECT_JUMP
|
||||
#define TBPARAM(x)
|
||||
#else
|
||||
#define TBPARAM(x) (long)(x)
|
||||
#endif
|
||||
|
||||
static inline void gen_op_goto_tb(int dummy, int n, long tb)
|
||||
{
|
||||
if (n == 0) {
|
||||
gen_op_goto_tb0(TBPARAM(tb));
|
||||
} else {
|
||||
gen_op_goto_tb1(TBPARAM(tb));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_z32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_z32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_nz32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_nz32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_s32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_s32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_ns32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_ns32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
1059
target-m68k/op.c
1059
target-m68k/op.c
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "exec.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
||||
@ -161,3 +162,71 @@ void do_interrupt(int is_hw)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void raise_exception(int tt)
|
||||
{
|
||||
env->exception_index = tt;
|
||||
cpu_loop_exit();
|
||||
}
|
||||
|
||||
void HELPER(raise_exception)(uint32_t tt)
|
||||
{
|
||||
raise_exception(tt);
|
||||
}
|
||||
|
||||
void HELPER(divu)(CPUState *env, uint32_t word)
|
||||
{
|
||||
uint32_t num;
|
||||
uint32_t den;
|
||||
uint32_t quot;
|
||||
uint32_t rem;
|
||||
uint32_t flags;
|
||||
|
||||
num = env->div1;
|
||||
den = env->div2;
|
||||
/* ??? This needs to make sure the throwing location is accurate. */
|
||||
if (den == 0)
|
||||
raise_exception(EXCP_DIV0);
|
||||
quot = num / den;
|
||||
rem = num % den;
|
||||
flags = 0;
|
||||
/* Avoid using a PARAM1 of zero. This breaks dyngen because it uses
|
||||
the address of a symbol, and gcc knows symbols can't have address
|
||||
zero. */
|
||||
if (word && quot > 0xffff)
|
||||
flags |= CCF_V;
|
||||
if (quot == 0)
|
||||
flags |= CCF_Z;
|
||||
else if ((int32_t)quot < 0)
|
||||
flags |= CCF_N;
|
||||
env->div1 = quot;
|
||||
env->div2 = rem;
|
||||
env->cc_dest = flags;
|
||||
}
|
||||
|
||||
void HELPER(divs)(CPUState *env, uint32_t word)
|
||||
{
|
||||
int32_t num;
|
||||
int32_t den;
|
||||
int32_t quot;
|
||||
int32_t rem;
|
||||
int32_t flags;
|
||||
|
||||
num = env->div1;
|
||||
den = env->div2;
|
||||
if (den == 0)
|
||||
raise_exception(EXCP_DIV0);
|
||||
quot = num / den;
|
||||
rem = num % den;
|
||||
flags = 0;
|
||||
if (word && quot != (int16_t)quot)
|
||||
flags |= CCF_V;
|
||||
if (quot == 0)
|
||||
flags |= CCF_Z;
|
||||
else if (quot < 0)
|
||||
flags |= CCF_N;
|
||||
env->div1 = quot;
|
||||
env->div2 = rem;
|
||||
env->cc_dest = flags;
|
||||
}
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
/* Load/store ops. */
|
||||
#define MEM_LD_OP(name,suffix) \
|
||||
OP(glue(glue(ld,name),MEMSUFFIX)) \
|
||||
{ \
|
||||
uint32_t addr = get_op(PARAM2); \
|
||||
set_op(PARAM1, glue(glue(ld,suffix),MEMSUFFIX)(addr)); \
|
||||
FORCE_RET(); \
|
||||
}
|
||||
|
||||
MEM_LD_OP(8u32,ub)
|
||||
MEM_LD_OP(8s32,sb)
|
||||
MEM_LD_OP(16u32,uw)
|
||||
MEM_LD_OP(16s32,sw)
|
||||
MEM_LD_OP(32,l)
|
||||
|
||||
#undef MEM_LD_OP
|
||||
|
||||
#define MEM_ST_OP(name,suffix) \
|
||||
OP(glue(glue(st,name),MEMSUFFIX)) \
|
||||
{ \
|
||||
uint32_t addr = get_op(PARAM1); \
|
||||
glue(glue(st,suffix),MEMSUFFIX)(addr, get_op(PARAM2)); \
|
||||
FORCE_RET(); \
|
||||
}
|
||||
|
||||
MEM_ST_OP(8,b)
|
||||
MEM_ST_OP(16,w)
|
||||
MEM_ST_OP(32,l)
|
||||
|
||||
#undef MEM_ST_OP
|
||||
|
||||
OP(glue(ldf64,MEMSUFFIX))
|
||||
{
|
||||
uint32_t addr = get_op(PARAM2);
|
||||
set_opf64(PARAM1, glue(ldfq,MEMSUFFIX)(addr));
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
OP(glue(stf64,MEMSUFFIX))
|
||||
{
|
||||
uint32_t addr = get_op(PARAM1);
|
||||
glue(stfq,MEMSUFFIX)(addr, get_opf64(PARAM2));
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#undef MEMSUFFIX
|
@ -1,37 +1,13 @@
|
||||
DEFO32(D0, dregs[0])
|
||||
DEFO32(D1, dregs[1])
|
||||
DEFO32(D2, dregs[2])
|
||||
DEFO32(D3, dregs[3])
|
||||
DEFO32(D4, dregs[4])
|
||||
DEFO32(D5, dregs[5])
|
||||
DEFO32(D6, dregs[6])
|
||||
DEFO32(D7, dregs[7])
|
||||
DEFO32(A0, aregs[0])
|
||||
DEFO32(A1, aregs[1])
|
||||
DEFO32(A2, aregs[2])
|
||||
DEFO32(A3, aregs[3])
|
||||
DEFO32(A4, aregs[4])
|
||||
DEFO32(A5, aregs[5])
|
||||
DEFO32(A6, aregs[6])
|
||||
DEFO32(SP, aregs[7]) /* A7 */
|
||||
DEFF64(F0, fregs[0])
|
||||
DEFF64(F1, fregs[1])
|
||||
DEFF64(F2, fregs[2])
|
||||
DEFF64(F3, fregs[3])
|
||||
DEFF64(F4, fregs[4])
|
||||
DEFF64(F5, fregs[5])
|
||||
DEFF64(F6, fregs[6])
|
||||
DEFF64(F7, fregs[7])
|
||||
DEFF64(FP_RESULT, fp_result)
|
||||
DEFO32(PC, pc)
|
||||
DEFO32(SR, sr)
|
||||
DEFO32(CC_OP, cc_op)
|
||||
DEFR(T0, AREG1, QMODE_I32)
|
||||
DEFO32(CC_DEST, cc_dest)
|
||||
DEFO32(CC_SRC, cc_src)
|
||||
DEFO32(CC_X, cc_x)
|
||||
DEFO32(DIV1, div1)
|
||||
DEFO32(DIV2, div2)
|
||||
DEFO32(EXCEPTION, exception_index)
|
||||
DEFO32(HALTED, halted)
|
||||
DEFO32(MACSR, macsr)
|
||||
DEFO32(MAC_MASK, mac_mask)
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user