diff --git a/include/asm/fixpoint.h b/include/asm/fixpoint.h index 537bb991..88a971d6 100644 --- a/include/asm/fixpoint.h +++ b/include/asm/fixpoint.h @@ -20,6 +20,7 @@ int32_t fix_ACos(int32_t i); int32_t fix_ATan(int32_t i); int32_t fix_ATan2(int32_t i, int32_t j); int32_t fix_Mul(int32_t i, int32_t j); +int32_t fix_Mod(int32_t i, int32_t j); int32_t fix_Div(int32_t i, int32_t j); int32_t fix_Pow(int32_t i, int32_t j); int32_t fix_Log(int32_t i, int32_t j); diff --git a/man/rgbasm.5 b/man/rgbasm.5 index 6a83e532..3e47411d 100644 --- a/man/rgbasm.5 +++ b/man/rgbasm.5 @@ -319,6 +319,7 @@ delim $$ .It Sy Name Ta Sy Operation .It Fn DIV x y Ta $x \[di] y$ .It Fn MUL x y Ta $x \[mu] y$ +.It Fn FMOD x y Ta $x % y$ .It Fn POW x y Ta $x$ to the $y$ power .It Fn LOG x y Ta Logarithm of $x$ to the base $y$ .It Fn ROUND x Ta Round $x$ to the nearest integer diff --git a/src/asm/fixpoint.c b/src/asm/fixpoint.c index 53823eff..af4b274a 100644 --- a/src/asm/fixpoint.c +++ b/src/asm/fixpoint.c @@ -119,6 +119,14 @@ int32_t fix_Div(int32_t i, int32_t j) return double2fix(fix2double(i) / fix2double(j)); } +/* + * Modulo + */ +int32_t fix_Mod(int32_t i, int32_t j) +{ + return double2fix(fmod(fix2double(i), fix2double(j))); +} + /* * Power */ diff --git a/src/asm/lexer.c b/src/asm/lexer.c index d0c3a01b..ea45d946 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -181,6 +181,7 @@ static struct KeywordMapping { {"FLOOR", T_OP_FLOOR}, {"DIV", T_OP_FDIV}, {"MUL", T_OP_FMUL}, + {"FMOD", T_OP_FMOD}, {"POW", T_OP_POW}, {"LOG", T_OP_LOG}, {"SIN", T_OP_SIN}, diff --git a/src/asm/parser.y b/src/asm/parser.y index 85dd5e63..9c020308 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -558,6 +558,7 @@ enum { %token T_OP_ASIN "ASIN" T_OP_ACOS "ACOS" T_OP_ATAN "ATAN" T_OP_ATAN2 "ATAN2" %token T_OP_FDIV "FDIV" %token T_OP_FMUL "FMUL" +%token T_OP_FMOD "FMOD" %token T_OP_POW "POW" %token T_OP_LOG "LOG" %token T_OP_ROUND "ROUND" @@ -1488,6 +1489,9 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); } | T_OP_FMUL T_LPAREN const T_COMMA const T_RPAREN { rpn_Number(&$$, fix_Mul($3, $5)); } + | T_OP_FMOD T_LPAREN const T_COMMA const T_RPAREN { + rpn_Number(&$$, fix_Mod($3, $5)); + } | T_OP_POW T_LPAREN const T_COMMA const T_RPAREN { rpn_Number(&$$, fix_Pow($3, $5)); } diff --git a/test/asm/math.asm b/test/asm/math.asm index 7411bb32..f0f207a8 100644 --- a/test/asm/math.asm +++ b/test/asm/math.asm @@ -23,6 +23,10 @@ ENDM assert MUL(10.0, 0.5) == 5.0 assert MUL(10.0, 0.0) == 0.0 + assert FMOD(5.0, 2.0) == 1.0 + assert FMOD(-5.0, 2.0) == -1.0 + assert FMOD(-5.0, 0.0) == $8000_0000 + assert POW(10.0, 2.0) == 100.0 assert POW(100.0, 0.5) == 10.0