Implement BITWIDTH and TZCOUNT functions (#1450)

This commit is contained in:
Sylvie
2024-08-07 10:39:30 -04:00
committed by GitHub
parent 7435630d6a
commit e93190d491
10 changed files with 105 additions and 18 deletions

View File

@@ -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) },

View File

@@ -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());
}

View File

@@ -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);

View File

@@ -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;