255 lines
3.8 KiB
Plaintext
255 lines
3.8 KiB
Plaintext
#####################################################
|
|
##### Macros #####
|
|
#####################################################
|
|
|
|
|
|
##### CARRY-Flag #####
|
|
|
|
macro set_CY_pos(var1, var2)
|
|
{
|
|
$(CY) = carry(var1, var2);
|
|
}
|
|
|
|
macro set_CY_pos2(var1, var2, var3)
|
|
{
|
|
local var12 = var1 + var2;
|
|
$(CY) = carry(var1, var2) || carry(var12, var3);
|
|
}
|
|
|
|
macro set_CY_neg(var1, var2)
|
|
{
|
|
$(CY) = var1 < var2;
|
|
}
|
|
|
|
macro set_CY_neg2(var1, var2, var3)
|
|
{
|
|
local var23 = var2 + var3;
|
|
$(CY) = (var1 < var23);
|
|
}
|
|
|
|
|
|
|
|
##### Overflow-Flag #####
|
|
|
|
macro set_OV_pos(var1, var2)
|
|
{
|
|
$(OV) = scarry(var1, var2);
|
|
}
|
|
|
|
macro set_OV_pos2(var1, var2, var3)
|
|
{
|
|
local var12 = var1 + var2;
|
|
$(OV) = scarry(var1, var2) || scarry(var12, var3);
|
|
}
|
|
|
|
macro set_OV_neg(var1, var2)
|
|
{
|
|
local A:4 = var1;
|
|
local B:4 = var2;
|
|
local R = A - B;
|
|
|
|
local A1 = A[31,1];
|
|
local B1 = B[31,1];
|
|
local R1 = R[31,1];
|
|
|
|
$(OV) = (A1 != B1) && (B1 == R1);
|
|
|
|
#OV = 1 if:
|
|
#pos - neg = neg
|
|
#neg - pos = pos
|
|
}
|
|
|
|
macro set_OV_neg2(var1, var2, var3)
|
|
{
|
|
local A:4 = var1;
|
|
local B:4 = var2;
|
|
local C:4 = var3;
|
|
local R = A - B - C;
|
|
|
|
local A1 = A[31,1];
|
|
local B1 = B[31,1];
|
|
local R1 = R[31,1];
|
|
|
|
$(OV) = (A1 != B1) && (B1 == R1);
|
|
}
|
|
|
|
|
|
|
|
##### S/Z-Flags #####
|
|
|
|
macro set_S(flag)
|
|
{
|
|
$(S) = flag s< 0;
|
|
}
|
|
|
|
macro set_Z(var)
|
|
{
|
|
$(Z) = var == 0;
|
|
}
|
|
|
|
|
|
|
|
##### General-Flag-Macros #####
|
|
|
|
macro set_general_flags_pos(var1, var2)
|
|
{
|
|
local res = var1 + var2;
|
|
set_CY_pos(var1, var2);
|
|
set_OV_pos(var1, var2);
|
|
set_S(res);
|
|
set_Z(res);
|
|
}
|
|
|
|
macro set_general_flags_neg(var1, var2)
|
|
{
|
|
local res = var1 - var2;
|
|
set_CY_neg(var1, var2);
|
|
set_OV_neg(var1, var2);
|
|
set_S(res);
|
|
set_Z(res);
|
|
}
|
|
|
|
macro set_OV0_S_Z(var)
|
|
{
|
|
$(OV) = 0;
|
|
set_S(var);
|
|
set_Z(var);
|
|
}
|
|
|
|
|
|
|
|
##### General-Macros #####
|
|
|
|
# if condition is != 0
|
|
macro either_or(res, cond, true, false)
|
|
{
|
|
res = (true * zext(cond != 0)) + (false * zext(cond == 0));
|
|
}
|
|
|
|
# if condition is == 1
|
|
macro either_or1(res, cond, true, false)
|
|
{
|
|
res = (true * zext(cond == 1)) + (false * zext(cond != 1));
|
|
}
|
|
|
|
macro shift_right_logic(res, var, shift_)
|
|
{
|
|
local shift = shift_ & 0x1f;
|
|
local mask = (zext(shift != 0) * var) & (1 << (shift - 1));
|
|
res = var >> shift;
|
|
set_OV0_S_Z(res);
|
|
$(CY) = ((mask != 0) && (shift != 0));
|
|
}
|
|
|
|
macro shift_right_arith(res, var, shift_)
|
|
{
|
|
local shift = shift_ & 0x1f;
|
|
local mask = (zext(shift != 0) * var) & (1 << (shift - 1));
|
|
res = var s>> shift;
|
|
set_OV0_S_Z(res);
|
|
$(CY) = ((mask != 0) && (shift != 0));
|
|
}
|
|
|
|
macro shift_left_logic(res, var, shift_)
|
|
{
|
|
local shift = shift_ & 0x1f;
|
|
local mask = (zext(shift != 0) * var) & (1 << (32 - shift));
|
|
res = var << shift;
|
|
set_OV0_S_Z(res);
|
|
$(CY) = ((mask != 0) && (shift != 0));
|
|
}
|
|
|
|
|
|
|
|
##### Prep/Disp Macros #####
|
|
|
|
macro push(reg)
|
|
{
|
|
sp = sp - 4;
|
|
*:4 sp = reg;
|
|
}
|
|
|
|
macro pop(reg)
|
|
{
|
|
reg = *:4 sp;
|
|
sp = sp + 4;
|
|
}
|
|
|
|
|
|
|
|
##### Search Macros #####
|
|
|
|
macro SearchRight(res, var, char)
|
|
{
|
|
local var_:4 = var;
|
|
res = 0;
|
|
|
|
<loop>
|
|
if ((var_ & 0x1) == char)
|
|
goto <end>;
|
|
|
|
var_ = var_ >> 1;
|
|
res = res + 1;
|
|
|
|
if (res < 32)
|
|
goto <loop>;
|
|
|
|
res = 0;
|
|
|
|
<end>
|
|
}
|
|
|
|
macro SearchLeft(res, var, char)
|
|
{
|
|
local var_:4 = var;
|
|
res = 0;
|
|
|
|
<loop>
|
|
if ((var_ >> 31) == char)
|
|
goto <end>;
|
|
|
|
var_ = var_ << 1;
|
|
res = res + 1;
|
|
|
|
if (res < 32)
|
|
goto <loop>;
|
|
|
|
res = 0;
|
|
|
|
<end>
|
|
}
|
|
|
|
# macro saturate(var)
|
|
# {
|
|
# if (var s> 0x7FFFFFFF)
|
|
# goto <pos_sat>;
|
|
|
|
# if (var s< -0x80000000)
|
|
# goto <neg_sat>;
|
|
|
|
# goto <end>;
|
|
|
|
# <pos_sat>
|
|
# var = 0x7FFFFFFF;
|
|
# goto <end>;
|
|
|
|
# <neg_sat>
|
|
# var = -0x80000000;
|
|
# goto <end>;
|
|
|
|
# <end>
|
|
# }
|
|
|
|
|
|
##### Float-Macros #####
|
|
|
|
macro compare_float(res, fcond, reg1, reg2)
|
|
{
|
|
local un = ((fcond & 1) == 1) & (nan(reg2) || nan(reg1));
|
|
local eq = ((fcond & 2) == 2) & (!(nan(reg2) || nan(reg1))) & (reg2 f== reg1);
|
|
local le = ((fcond & 4) == 4) & (!(nan(reg2) || nan(reg1))) & (reg2 f< reg1);
|
|
#local ex = (fcond & 8) & ((nan(reg2) || nan(reg1)));
|
|
|
|
res = zext(un|eq|le);
|
|
}
|