mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-22 11:12:07 +00:00
Implement BITWIDTH and TZCOUNT functions (#1450)
This commit is contained in:
@@ -237,6 +237,9 @@ static std::unordered_map<std::string, int, CaseInsensitive, CaseInsensitive> ke
|
||||
{"LOW", T_(OP_LOW) },
|
||||
{"ISCONST", T_(OP_ISCONST) },
|
||||
|
||||
{"BITWIDTH", T_(OP_BITWIDTH) },
|
||||
{"TZCOUNT", T_(OP_TZCOUNT) },
|
||||
|
||||
{"STRCMP", T_(OP_STRCMP) },
|
||||
{"STRIN", T_(OP_STRIN) },
|
||||
{"STRRIN", T_(OP_STRRIN) },
|
||||
|
||||
@@ -174,6 +174,8 @@
|
||||
%type <int32_t> opt_q_arg
|
||||
|
||||
%token OP_HIGH "HIGH" OP_LOW "LOW"
|
||||
%token OP_BITWIDTH "BITWIDTH"
|
||||
%token OP_TZCOUNT "TZCOUNT"
|
||||
%token OP_ISCONST "ISCONST"
|
||||
|
||||
%token OP_STRCMP "STRCMP"
|
||||
@@ -1349,6 +1351,12 @@ relocexpr_no_str:
|
||||
| OP_LOW LPAREN relocexpr RPAREN {
|
||||
$$.makeUnaryOp(RPN_LOW, std::move($3));
|
||||
}
|
||||
| OP_BITWIDTH LPAREN relocexpr RPAREN {
|
||||
$$.makeUnaryOp(RPN_BITWIDTH, std::move($3));
|
||||
}
|
||||
| OP_TZCOUNT LPAREN relocexpr RPAREN {
|
||||
$$.makeUnaryOp(RPN_TZCOUNT, std::move($3));
|
||||
}
|
||||
| OP_ISCONST LPAREN relocexpr RPAREN {
|
||||
$$.makeNumber($3.isKnown());
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <string.h>
|
||||
#include <string_view>
|
||||
|
||||
#include "helpers.hpp" // assume
|
||||
#include "helpers.hpp" // assume, clz, ctz
|
||||
#include "opmath.hpp"
|
||||
|
||||
#include "asm/output.hpp"
|
||||
@@ -319,6 +319,12 @@ void Expression::makeUnaryOp(RPNCommand op, Expression &&src) {
|
||||
case RPN_LOW:
|
||||
data = val & 0xFF;
|
||||
break;
|
||||
case RPN_BITWIDTH:
|
||||
data = val != 0 ? 32 - clz((uint32_t)val) : 0;
|
||||
break;
|
||||
case RPN_TZCOUNT:
|
||||
data = val != 0 ? ctz((uint32_t)val) : 32;
|
||||
break;
|
||||
|
||||
case RPN_LOGOR:
|
||||
case RPN_LOGAND:
|
||||
@@ -498,6 +504,8 @@ void Expression::makeBinaryOp(RPNCommand op, Expression &&src1, Expression const
|
||||
case RPN_RST:
|
||||
case RPN_HIGH:
|
||||
case RPN_LOW:
|
||||
case RPN_BITWIDTH:
|
||||
case RPN_TZCOUNT:
|
||||
case RPN_CONST:
|
||||
case RPN_SYM:
|
||||
fatalerror("%d is not a binary operator\n", op);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "helpers.hpp" // assume
|
||||
#include "helpers.hpp" // assume, clz, ctz
|
||||
#include "linkdefs.hpp"
|
||||
#include "opmath.hpp"
|
||||
|
||||
@@ -146,6 +146,15 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
value = popRPN(patch) & 0xFF;
|
||||
break;
|
||||
|
||||
case RPN_BITWIDTH:
|
||||
value = popRPN(patch);
|
||||
value = value != 0 ? 32 - clz((uint32_t)value) : 0;
|
||||
break;
|
||||
case RPN_TZCOUNT:
|
||||
value = popRPN(patch);
|
||||
value = value != 0 ? ctz((uint32_t)value) : 32;
|
||||
break;
|
||||
|
||||
case RPN_OR:
|
||||
value = popRPN(patch) | popRPN(patch);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user