summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 33dd153)
raw | patch | inline | side by side (parent: 33dd153)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Wed, 26 Jul 2017 19:36:35 +0000 (22:36 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Wed, 26 Jul 2017 19:36:35 +0000 (22:36 +0300) |
src/backends/jvm/generator-jvm.c | patch | blob | history | |
src/backends/jvm/generator-jvm.h | patch | blob | history | |
src/test.c | patch | blob | history | |
tst.java | [deleted file] | patch | blob | history |
index c217ccb3d6f37ebb809bf076dcd35e62636d3c5e..b0c54ff1d967aab8a5126d43f1313a344be408f4 100644 (file)
else
{
assert(i <= MAX_REGISTERS);
- rf -> num_used += 2;
+ rf -> num_used += 1;
rf -> reg[i].used = true;
rf -> reg[i].wide = false;
}
}
}
+static int
+jvm_new_label_id(oberon_context_t * ctx)
+{
+ gen_context_t * c = ctx -> gen_context;
+ int label_id = c -> label_id;
+ c -> label_id += 1;
+ return label_id;
+}
+
+static char *
+jvm_get_label_name(int label_id)
+{
+ return new_string("L%i", label_id);
+}
+
static void
-push_operator(oberon_context_t * ctx, FILE * fp, oberon_oper_t * oper)
+jvm_generate_label(FILE * fp, int label_id)
{
- char prefix = get_prefix(ctx, oper -> result);
- switch(oper -> op)
+ fprintf(fp, "L%i:\n", label_id);
+}
+
+static void
+jvm_generate_logical_not(oberon_context_t * ctx, FILE * fp)
+{
+ int label_true = jvm_new_label_id(ctx);
+ int label_false = jvm_new_label_id(ctx);
+ char * label_name_true = jvm_get_label_name(label_true);
+ char * label_name_false = jvm_get_label_name(label_false);
+
+ fprintf(fp, "ifne %s\n", label_name_false);
+ fprintf(fp, "iconst_1\n");
+ fprintf(fp, "goto %s\n", label_name_true);
+ jvm_generate_label(fp, label_false);
+ fprintf(fp, "iconst_0\n");
+ jvm_generate_label(fp, label_true);
+}
+
+static char
+jvm_get_type_of_prefix(char prefix)
+{
+ switch(prefix)
+ {
+ case 'b':
+ return 'B';
+ case 'c':
+ return 'C';
+ case 'd':
+ return 'D';
+ case 'f':
+ return 'F';
+ case 'i':
+ return 'I';
+ case 'l':
+ return 'J';
+ }
+
+ assert(0);
+}
+
+static void
+jvm_generate_abs(FILE * fp, char prefix)
+{
+ char t = jvm_get_type_of_prefix(prefix);
+ fprintf(fp, "invokestatic java/lang/Math/abs(%c)%c\n", t, t);
+}
+
+static void
+jvm_generate_compare_op(oberon_context_t * ctx, FILE *fp, char prefix, int op)
+{
+ int label_true = jvm_new_label_id(ctx);
+ int label_false = jvm_new_label_id(ctx);
+ char * label_name_true = jvm_get_label_name(label_true);
+ char * label_name_false = jvm_get_label_name(label_false);
+
+ assert(prefix == 'i' || prefix == 'a');
+
+ switch(op)
+ {
+ case OP_EQ:
+ fprintf(fp, "if_%ccmpeq %s\n", prefix, label_name_true);
+ break;
+ case OP_NEQ:
+ fprintf(fp, "if_%ccmpne %s\n", prefix, label_name_true);
+ break;
+ case OP_LSS:
+ fprintf(fp, "if_icmplt %s\n", label_name_true);
+ break;
+ case OP_LEQ:
+ fprintf(fp, "if_icmple %s\n", label_name_true);
+ break;
+ case OP_GRT:
+ fprintf(fp, "if_icmpgt %s\n", label_name_true);
+ break;
+ case OP_GEQ:
+ fprintf(fp, "if_icmpge %s\n", label_name_true);
+ break;
+ default:
+ oberon_error(ctx, "jvm_generate_compare_op: wat");
+ break;
+ }
+
+ fprintf(fp, "iconst_0\n");
+ fprintf(fp, "goto %s\n", label_name_false);
+ jvm_generate_label(fp, label_true);
+ fprintf(fp, "iconst_1\n");
+ jvm_generate_label(fp, label_false);
+}
+
+static void
+jvm_generate_operator(oberon_context_t * ctx, FILE *fp, char prefix, int op)
+{
+ switch(op)
{
case OP_UNARY_MINUS:
- push_expr(ctx, fp, oper -> left);
fprintf(fp, "%cneg\n", prefix);
break;
case OP_BITWISE_NOT:
- push_expr(ctx, fp, oper -> left);
push_int(fp, -1);
fprintf(fp, "%cxor\n", prefix);
break;
+ case OP_LOGIC_NOT:
+ jvm_generate_logical_not(ctx, fp);
+ break;
+ case OP_ABS:
+ jvm_generate_abs(fp, prefix);
+ break;
case OP_ADD:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%cadd\n", prefix);
break;
case OP_SUB:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%csub\n", prefix);
break;
case OP_MUL:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%cmul\n", prefix);
break;
case OP_DIV:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%cdiv\n", prefix);
break;
case OP_MOD:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%crem\n", prefix);
break;
case OP_BITWISE_AND:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%cand\n", prefix);
break;
case OP_BITWISE_XOR:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%cxor\n", prefix);
break;
case OP_BITWISE_OR:
- push_expr(ctx, fp, oper -> left);
- push_expr(ctx, fp, oper -> right);
fprintf(fp, "%cor\n", prefix);
break;
case OP_LEQ:
case OP_GRT:
case OP_GEQ:
+ jvm_generate_compare_op(ctx, fp, prefix, op);
+ break;
+ default:
+ oberon_error(ctx, "jvm_generate_operator: unk op %i", op);
+ break;
+ }
+}
+
+static void
+push_operator(oberon_context_t * ctx, FILE * fp, oberon_oper_t * oper)
+{
+ char prefix = get_prefix(ctx, oper -> result);
+ int op = oper -> op;
+ switch(op)
+ {
+ case OP_UNARY_MINUS:
+ case OP_BITWISE_NOT:
case OP_LOGIC_NOT:
case OP_ABS:
- oberon_error(ctx, "push_oper: TODO op %i", oper -> op);
+ push_expr(ctx, fp, oper -> left);
+ jvm_generate_operator(ctx, fp, prefix, op);
break;
+
+ case OP_ADD:
+ case OP_SUB:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_MOD:
+ case OP_BITWISE_AND:
+ case OP_BITWISE_XOR:
+ case OP_BITWISE_OR:
+
+ case OP_EQ:
+ case OP_NEQ:
+ case OP_LSS:
+ case OP_LEQ:
+ case OP_GRT:
+ case OP_GEQ:
+ push_expr(ctx, fp, oper -> left);
+ push_expr(ctx, fp, oper -> right);
+ jvm_generate_operator(ctx, fp, prefix, op);
+ break;
+
default:
- oberon_error(ctx, "push_oper: unk op %i", oper -> op);
+ oberon_error(ctx, "push_oper: unk op %i", op);
break;
}
}
index 01c29ee481785830c6e0e0999be79b179f63f44c..3ccc9f50ac3cbdfd6563aab5d0ef208320e90a27 100644 (file)
{
gen_module_t * m;
struct gen_register_file * rf;
+ int label_id;
};
struct gen_module_t
diff --git a/src/test.c b/src/test.c
index eb1008c986bb52159572b33fe4f80bd205ab6b91..96e160a7087354a4e07b77900298aacdf9e235ba 100644 (file)
--- a/src/test.c
+++ b/src/test.c
"MODULE Test;"
"VAR"
" x : INTEGER;"
+ " b : BOOLEAN;"
""
"PROCEDURE Tier(x : INTEGER) : INTEGER;"
"VAR"
"END Tier;"
""
"BEGIN;"
- " x := Tier(666);"
+ " x := ABS(-666);"
+ " x := Tier(x);"
+ " b := ~TRUE;"
"END Test."
;
diff --git a/tst.java b/tst.java
--- a/tst.java
+++ /dev/null
@@ -1,4 +0,0 @@
-public abstract class tst
-{
- public abstract void invoke();
-}