Skip to content

Commit

Permalink
Support modulo operator
Browse files Browse the repository at this point in the history
  • Loading branch information
eecheng87 committed Nov 5, 2020
1 parent d4d626b commit ff645b9
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 2 deletions.
18 changes: 18 additions & 0 deletions src/cfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ typedef enum {
T_close_square, /* ] */
T_asterisk, /* '*' */
T_divide, /* / */
T_mod, /* % */
T_bit_or, /* | */
T_bit_xor, /* ^ */
T_log_and, /* && */
Expand Down Expand Up @@ -338,6 +339,10 @@ token_t get_next_token()
skip_whitespace();
return T_lt;
}
if (next_char == '%') {
read_char(1);
return T_mod;
}
if (next_char == '>') {
read_char(0);
if (next_char == '=') {
Expand Down Expand Up @@ -876,6 +881,7 @@ int get_operator_prio(opcode_t op)
return 12;
case OP_mul:
case OP_div:
case OP_mod:
return 13;
default:
return 0;
Expand All @@ -893,6 +899,8 @@ opcode_t get_operator()
op = OP_mul;
else if (lex_accept(T_divide))
op = OP_div;
else if (lex_accept(T_mod))
op = OP_mod;
else if (lex_accept(T_lshift))
op = OP_lshift;
else if (lex_accept(T_rshift))
Expand Down Expand Up @@ -1357,6 +1365,7 @@ int read_numeric_sconstant()
int eval_expression_imm(opcode_t op, int op1, int op2)
{
/* return immediate result */
int tmp = op2;
int res = 0;
switch (op) {
case OP_add:
Expand All @@ -1371,6 +1380,15 @@ int eval_expression_imm(opcode_t op, int op1, int op2)
case OP_div:
res = op1 / op2;
break;
case OP_mod:
/* TODO: provide arithmetic & operation instead of '&=' */
tmp &= (tmp - 1);
if ((op2 != 0) && (tmp == 0)) {
res = op1;
res &= (op2 - 1);
} else
res = op1 % op2;
break;
case OP_lshift:
res = op1 << op2;
break;
Expand Down
9 changes: 9 additions & 0 deletions src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ int get_code_length(ir_instr_t *ii)
case OP_func_exit:
return 16;
case OP_exit:
case OP_mod:
return 12;
case OP_load_data_address:
case OP_jz:
Expand Down Expand Up @@ -367,6 +368,14 @@ void code_generate()
if (dump_ir == 1)
printf(" x%d /= x%d", dest_reg, OP_reg);
break;
case OP_mod:
emit(__div(__AL, OP_reg + 1, OP_reg, dest_reg));
emit(__mul(__AL, OP_reg, OP_reg, OP_reg + 1));
emit(__sub_r(__AL, dest_reg, dest_reg, OP_reg));
/* TODO: support percent-sign character (%) in format string */
if (dump_ir == 1)
printf(" x%d = x%d mod x%d", dest_reg, dest_reg, OP_reg);
break;
case OP_negate:
emit(__rsb_i(__AL, dest_reg, 0, dest_reg));
if (dump_ir == 1)
Expand Down
1 change: 1 addition & 0 deletions src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef enum {
OP_sub,
OP_mul,
OP_div, /* signed division */
OP_mod, /* modulo */
OP_lshift,
OP_rshift,
OP_log_and,
Expand Down
4 changes: 2 additions & 2 deletions tests/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ expr 55 "1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + 10))))))))"
# expr 21 "+1+20"
# expr 10 "-15+(+35-10)"

# expr 2 "5 % 3"
# expr 6 "111 % 7"
expr 2 "5 % 3"
expr 6 "111 % 7"

expr 1 "10 > 5"
expr 1 "3+3 > 5"
Expand Down

0 comments on commit ff645b9

Please sign in to comment.