From: DeaDDooMER Date: Wed, 26 Jul 2017 19:36:35 +0000 (+0300) Subject: JVM: Добавлено больше операторов X-Git-Url: https://deadsoftware.ru/gitweb?p=dsw-obn.git;a=commitdiff_plain;h=238463393ee054792c7d75374ce6f874a6963ce3 JVM: Добавлено больше операторов --- diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index c217ccb..b0c54ff 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -491,7 +491,7 @@ jvm_alloc_register(struct gen_register_file * rf, oberon_type_t * type) else { assert(i <= MAX_REGISTERS); - rf -> num_used += 2; + rf -> num_used += 1; rf -> reg[i].used = true; rf -> reg[i].wide = false; } @@ -754,60 +754,155 @@ push_item(oberon_context_t * ctx, FILE * fp, oberon_item_t * item) } } +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; @@ -817,12 +912,51 @@ push_operator(oberon_context_t * ctx, FILE * fp, oberon_oper_t * oper) 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; } } diff --git a/src/backends/jvm/generator-jvm.h b/src/backends/jvm/generator-jvm.h index 01c29ee..3ccc9f5 100644 --- a/src/backends/jvm/generator-jvm.h +++ b/src/backends/jvm/generator-jvm.h @@ -36,6 +36,7 @@ struct gen_context_t { 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 eb1008c..96e160a 100644 --- a/src/test.c +++ b/src/test.c @@ -9,6 +9,7 @@ static char source_test[] = "MODULE Test;" "VAR" " x : INTEGER;" + " b : BOOLEAN;" "" "PROCEDURE Tier(x : INTEGER) : INTEGER;" "VAR" @@ -19,7 +20,9 @@ static char source_test[] = "END Tier;" "" "BEGIN;" - " x := Tier(666);" + " x := ABS(-666);" + " x := Tier(x);" + " b := ~TRUE;" "END Test." ; diff --git a/tst.java b/tst.java deleted file mode 100644 index 2dae5b2..0000000 --- a/tst.java +++ /dev/null @@ -1,4 +0,0 @@ -public abstract class tst -{ - public abstract void invoke(); -}