From b0e035d530703681f715189e68410f80efc7f012 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 22 Feb 2024 20:35:45 +0000 Subject: [PATCH] Use foreign functions for predefined FILE_CLOSE and ENDFILE --- src/common.c | 2 -- src/jit/jit-dump.c | 4 ++-- src/jit/jit-exits.c | 40 ---------------------------------------- src/jit/jit-exits.h | 2 -- src/jit/jit-irgen.c | 24 ------------------------ src/jit/jit-priv.h | 2 -- src/lower.c | 35 +++++++++++++++++++---------------- src/object.c | 2 +- src/parse.c | 1 + src/rt/fileio.c | 28 ++++++++++++++++++++++++++++ src/symbols.txt | 2 ++ src/vcode.c | 39 +-------------------------------------- src/vcode.h | 4 ---- test/test_lower.c | 15 ++++----------- 14 files changed, 58 insertions(+), 142 deletions(-) diff --git a/src/common.c b/src/common.c index 86f7b599..fdd948df 100644 --- a/src/common.c +++ b/src/common.c @@ -1397,10 +1397,8 @@ bool is_open_coded_builtin(subprogram_kind_t kind) case S_SCALAR_XNOR: case S_FILE_OPEN1: case S_FILE_OPEN2: - case S_FILE_CLOSE: case S_FILE_READ: case S_FILE_WRITE: - case S_ENDFILE: case S_DEALLOCATE: return true; default: diff --git a/src/jit/jit-dump.c b/src/jit/jit-dump.c index dd1941ec..f785c4fa 100644 --- a/src/jit/jit-dump.c +++ b/src/jit/jit-dump.c @@ -80,8 +80,8 @@ const char *jit_exit_name(jit_exit_t exit) "DIV_ZERO", "EXPONENT_FAIL", "REPORT", "ASSERT_FAIL", "RANGE_FAIL", "FUNC_WAIT", "INIT_SIGNAL", "DRIVE_SIGNAL", "SCHED_WAVEFORM", "SCHED_PROCESS", "TEST_EVENT", "TEST_ACTIVE", "SCHED_EVENT", - "FILE_OPEN", "FILE_CLOSE","FILE_READ", "FILE_WRITE", "ENDFILE", - "DEBUG_OUT", "ALIAS_SIGNAL", "MAP_SIGNAL", "MAP_CONST", "RESOLVE_SIGNAL", + "FILE_OPEN", "FILE_READ", "FILE_WRITE", "DEBUG_OUT", + "ALIAS_SIGNAL", "MAP_SIGNAL", "MAP_CONST", "RESOLVE_SIGNAL", "LAST_EVENT", "LAST_ACTIVE", "DISCONNECT", "ELAB_ORDER_FAIL", "FORCE", "RELEASE", "PUSH_SCOPE", "POP_SCOPE", "IMPLICIT_SIGNAL", "DRIVING", "DRIVING_VALUE", "CLAIM_TLAB", "COVER_TOGGLE", "PROCESS_INIT", diff --git a/src/jit/jit-exits.c b/src/jit/jit-exits.c index 29e23f5c..ff6d05ee 100644 --- a/src/jit/jit-exits.c +++ b/src/jit/jit-exits.c @@ -119,32 +119,6 @@ int64_t x_file_read(void **_fp, uint8_t *data, int64_t size, int64_t count) return fread(data, size, count, *fp); } -void x_file_close(void **_fp) -{ - FILE **fp = (FILE **)_fp; - - if (*fp != NULL) { - fclose(*fp); - *fp = NULL; - } -} - -int8_t x_endfile(void *_f) -{ - FILE *f = _f; - - if (f == NULL) - jit_msg(NULL, DIAG_FATAL, "ENDFILE called on closed file"); - - int c = fgetc(f); - if (c == EOF) - return 1; - else { - ungetc(c, f); - return 0; - } -} - void x_index_fail(int64_t value, int64_t left, int64_t right, int8_t dir, tree_t where, tree_t hint) { @@ -799,13 +773,6 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args, } break; - case JIT_EXIT_FILE_CLOSE: - { - void **_fp = args[0].pointer; - x_file_close(_fp); - } - break; - case JIT_EXIT_FILE_READ: { void **_fp = args[0].pointer; @@ -827,13 +794,6 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args, } break; - case JIT_EXIT_ENDFILE: - { - void *_fp = args[0].pointer; - args[0].integer = x_endfile(_fp); - } - break; - case JIT_EXIT_DEBUG_OUT: { int64_t value = args[0].integer; diff --git a/src/jit/jit-exits.h b/src/jit/jit-exits.h index 392a38b0..30042868 100644 --- a/src/jit/jit-exits.h +++ b/src/jit/jit-exits.h @@ -47,8 +47,6 @@ void x_file_open(int8_t *status, void **_fp, const uint8_t *name_bytes, int32_t name_len, int8_t mode); void x_file_write(void **_fp, uint8_t *data, int64_t len); int64_t x_file_read(void **_fp, uint8_t *data, int64_t size, int64_t count); -void x_file_close(void **_fp); -int8_t x_endfile(void *_f); void x_index_fail(int64_t value, int64_t left, int64_t right, int8_t dir, tree_t where, tree_t hint); void x_length_fail(int64_t left, int64_t right, int32_t dim, tree_t where); diff --git a/src/jit/jit-irgen.c b/src/jit/jit-irgen.c index e65c85d0..00091442 100644 --- a/src/jit/jit-irgen.c +++ b/src/jit/jit-irgen.c @@ -2899,14 +2899,6 @@ static void irgen_op_file_open(jit_irgen_t *g, int op) macro_exit(g, JIT_EXIT_FILE_OPEN); } -static void irgen_op_file_close(jit_irgen_t *g, int op) -{ - jit_value_t file = irgen_get_arg(g, op, 0); - - j_send(g, 0, file); - macro_exit(g, JIT_EXIT_FILE_CLOSE); -} - static void irgen_op_file_read(jit_irgen_t *g, int op) { jit_value_t file = irgen_get_arg(g, op, 0); @@ -2967,16 +2959,6 @@ static void irgen_op_file_write(jit_irgen_t *g, int op) macro_exit(g, JIT_EXIT_FILE_WRITE); } -static void irgen_op_endfile(jit_irgen_t *g, int op) -{ - jit_value_t file = irgen_get_arg(g, op, 0); - - j_send(g, 0, file); - macro_exit(g, JIT_EXIT_ENDFILE); - - g->map[vcode_get_result(op)] = j_recv(g, 0); -} - static void irgen_op_push_scope(jit_irgen_t *g, int op) { jit_value_t locus = irgen_get_arg(g, op, 0); @@ -3781,18 +3763,12 @@ static void irgen_block(jit_irgen_t *g, vcode_block_t block) case VCODE_OP_FILE_OPEN: irgen_op_file_open(g, i); break; - case VCODE_OP_FILE_CLOSE: - irgen_op_file_close(g, i); - break; case VCODE_OP_FILE_READ: irgen_op_file_read(g, i); break; case VCODE_OP_FILE_WRITE: irgen_op_file_write(g, i); break; - case VCODE_OP_ENDFILE: - irgen_op_endfile(g, i); - break; case VCODE_OP_PUSH_SCOPE: irgen_op_push_scope(g, i); break; diff --git a/src/jit/jit-priv.h b/src/jit/jit-priv.h index e80533b7..497c0582 100644 --- a/src/jit/jit-priv.h +++ b/src/jit/jit-priv.h @@ -132,10 +132,8 @@ typedef enum { JIT_EXIT_TEST_ACTIVE, JIT_EXIT_SCHED_EVENT, JIT_EXIT_FILE_OPEN, - JIT_EXIT_FILE_CLOSE, JIT_EXIT_FILE_READ, JIT_EXIT_FILE_WRITE, - JIT_EXIT_ENDFILE, JIT_EXIT_DEBUG_OUT, JIT_EXIT_ALIAS_SIGNAL, JIT_EXIT_MAP_SIGNAL, diff --git a/src/lower.c b/src/lower.c index 29f481d9..b351a32f 100644 --- a/src/lower.c +++ b/src/lower.c @@ -2324,8 +2324,6 @@ static vcode_reg_t lower_builtin(lower_unit_t *lu, tree_t fcall, return lower_logical(lu, fcall, emit_xor(r0, r1), r0, r1, builtin, 0); case S_SCALAR_XNOR: return lower_logical(lu, fcall, emit_xnor(r0, r1), r0, r1, builtin, 0); - case S_ENDFILE: - return emit_endfile(r0); case S_FILE_OPEN1: { vcode_reg_t name = lower_array_data(r1); @@ -2355,9 +2353,6 @@ static vcode_reg_t lower_builtin(lower_unit_t *lu, tree_t fcall, emit_file_write(r0, data, length); return VCODE_INVALID_REG; } - case S_FILE_CLOSE: - emit_file_close(r0); - return VCODE_INVALID_REG; case S_FILE_READ: { vcode_reg_t inlen = VCODE_INVALID_REG; @@ -6546,20 +6541,22 @@ static void lower_leave_subprogram(lower_unit_t *lu) case T_FILE_DECL: { - vcode_block_t open_bb = emit_block(); - vcode_block_t closed_bb = emit_block(); + type_t base = type_base_recur(tree_type(d)); - vcode_reg_t ptr_reg = lower_var_ref(lu, d, EXPR_LVALUE); - vcode_reg_t file_reg = emit_load_indirect(ptr_reg); - vcode_reg_t null_reg = emit_null(lower_type(tree_type(d))); - vcode_reg_t cmp_reg = emit_cmp(VCODE_CMP_EQ, file_reg, null_reg); - emit_cond(cmp_reg, closed_bb, open_bb); + LOCAL_TEXT_BUF tb = tb_new(); + tb_istr(tb, ident_runtil(type_ident(base), '.')); + tb_cat(tb, ".FILE_CLOSE("); + mangle_one_type(tb, base); + tb_cat(tb, ")"); + tb_cat(tb, "$predef"); - vcode_select_block(open_bb); - emit_file_close(ptr_reg); - emit_jump(closed_bb); + ident_t func = ident_new(tb_get(tb)); - vcode_select_block(closed_bb); + vcode_reg_t ptr_reg = lower_var_ref(lu, d, EXPR_LVALUE); + vcode_reg_t context_reg = lower_context_for_call(lu, func); + vcode_reg_t args[] = { context_reg, ptr_reg }; + emit_fcall(func, VCODE_INVALID_TYPE, VCODE_INVALID_TYPE, + args, ARRAY_LEN(args)); } break; @@ -11011,6 +11008,12 @@ static void lower_predef(lower_unit_t *lu, object_t *obj) case S_FILE_OPEN3: lower_predef_file_open3(lu, decl); break; + case S_FILE_CLOSE: + lower_foreign_predef(lu, decl, "__nvc_file_close"); + break; + case S_ENDFILE: + lower_foreign_predef(lu, decl, "__nvc_endfile"); + break; case S_FILE_MODE: lower_foreign_predef(lu, decl, "__nvc_file_mode"); break; diff --git a/src/object.c b/src/object.c index 542b4b9c..1932cec9 100644 --- a/src/object.c +++ b/src/object.c @@ -405,7 +405,7 @@ void object_one_time_init(void) // Increment this each time a incompatible change is made to // the on-disk format not expressed in the object items table - const uint32_t format_fudge = 36; + const uint32_t format_fudge = 37; format_digest += format_fudge * UINT32_C(2654435761); diff --git a/src/parse.c b/src/parse.c index 8e3fa147..8c684d6c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1224,6 +1224,7 @@ static void declare_predefined_ops(tree_t container, type_t t) tree_t file_close = builtin_proc(file_close_i, S_FILE_CLOSE); add_port(file_close, "F", t, PORT_INOUT, NULL); + mangle_func(nametab, file_close); insert_name(nametab, file_close, file_close_i); tree_add_decl(container, file_close); diff --git a/src/rt/fileio.c b/src/rt/fileio.c index 4c013f45..70a8ec36 100644 --- a/src/rt/fileio.c +++ b/src/rt/fileio.c @@ -56,6 +56,34 @@ typedef enum { READ_WRITE_MODE } file_open_kind_t; +DLLEXPORT +void __nvc_file_close(jit_scalar_t *args) +{ + FILE **fp = args[2].pointer; + + if (*fp != NULL) { + fclose(*fp); + *fp = NULL; + } +} + +DLLEXPORT +void __nvc_endfile(jit_scalar_t *args) +{ + FILE **fp = args[1].pointer; + + if (*fp == NULL) + jit_msg(NULL, DIAG_FATAL, "ENDFILE called on closed file"); + + int c = fgetc(*fp); + if (c == EOF) + args[0].integer = 1; + else { + ungetc(c, *fp); + args[0].integer = 0; + } +} + DLLEXPORT void __nvc_flush(jit_scalar_t *args) { diff --git a/src/symbols.txt b/src/symbols.txt index 9a264b67..3cd3598b 100644 --- a/src/symbols.txt +++ b/src/symbols.txt @@ -53,7 +53,9 @@ _nvc_ieee_warnings; # Exported from src/rt/fileio.c + __nvc_endfile; __nvc_file_canseek; + __nvc_file_close; __nvc_file_mode; __nvc_file_position; __nvc_file_size; diff --git a/src/vcode.c b/src/vcode.c index 2521344a..e3014ac0 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -501,7 +501,6 @@ void vcode_heap_allocate(vcode_reg_t reg) case VCODE_OP_ABS: case VCODE_OP_MOD: case VCODE_OP_REM: - case VCODE_OP_ENDFILE: case VCODE_OP_ADD: case VCODE_OP_TRAP_ADD: case VCODE_OP_TRAP_SUB: @@ -946,7 +945,7 @@ const char *vcode_op_string(vcode_op_t op) "select", "or", "wrap", "uarray left", "uarray right", "uarray dir", "unwrap", "not", "and", "event", "active", "const record", "record ref", "copy", "sched event", "pcall", "resume", "xor", "xnor", "nand", "nor", - "memset", "case", "endfile", "file open", "file write", "file close", + "memset", "case", "file open", "file write", "file read", "null", "new", "null check", "deallocate", "all", "const real", "last event", "debug out", "cover stmt", "cover branch", "cover toggle", "cover expr", "cover state", "uarray len", "undefined", @@ -1959,15 +1958,6 @@ void vcode_dump_with_mark(int mark_op, vcode_dump_fn_t callback, void *arg) } break; - case VCODE_OP_ENDFILE: - { - col += vcode_dump_reg(op->result); - col += printf(" := %s ", vcode_op_string(op->kind)); - col += vcode_dump_reg(op->args.items[0]); - vcode_dump_result_type(col, op); - } - break; - case VCODE_OP_FILE_OPEN: { printf("%s ", vcode_op_string(op->kind)); @@ -1985,13 +1975,6 @@ void vcode_dump_with_mark(int mark_op, vcode_dump_fn_t callback, void *arg) } break; - case VCODE_OP_FILE_CLOSE: - { - printf("%s ", vcode_op_string(op->kind)); - vcode_dump_reg(op->args.items[0]); - } - break; - case VCODE_OP_FILE_WRITE: { printf("%s ", vcode_op_string(op->kind)); @@ -5262,17 +5245,6 @@ void emit_case(vcode_reg_t value, vcode_block_t def, const vcode_reg_t *cases, } } -vcode_reg_t emit_endfile(vcode_reg_t file) -{ - op_t *op = vcode_add_op(VCODE_OP_ENDFILE); - vcode_add_arg(op, file); - - VCODE_ASSERT(vtype_kind(vcode_reg_type(file)) == VCODE_TYPE_FILE, - "endfile argument must have file type"); - - return (op->result = vcode_add_reg(vtype_bool())); -} - void emit_file_open(vcode_reg_t file, vcode_reg_t name, vcode_reg_t length, vcode_reg_t kind, vcode_reg_t status) { @@ -5300,15 +5272,6 @@ void emit_file_write(vcode_reg_t file, vcode_reg_t value, vcode_reg_t length) "file write first argument must have file pointer type"); } -void emit_file_close(vcode_reg_t file) -{ - op_t *op = vcode_add_op(VCODE_OP_FILE_CLOSE); - vcode_add_arg(op, file); - - VCODE_ASSERT(vtype_is_pointer(vcode_reg_type(file), VCODE_TYPE_FILE), - "file close argument must have file pointer type"); -} - void emit_file_read(vcode_reg_t file, vcode_reg_t ptr, vcode_reg_t inlen, vcode_reg_t outlen) { diff --git a/src/vcode.h b/src/vcode.h index c54cf275..f5ac6189 100644 --- a/src/vcode.h +++ b/src/vcode.h @@ -89,10 +89,8 @@ typedef enum { VCODE_OP_NOR, VCODE_OP_MEMSET, VCODE_OP_CASE, - VCODE_OP_ENDFILE, VCODE_OP_FILE_OPEN, VCODE_OP_FILE_WRITE, - VCODE_OP_FILE_CLOSE, VCODE_OP_FILE_READ, VCODE_OP_NULL, VCODE_OP_NEW, @@ -458,11 +456,9 @@ void emit_resume(ident_t func); void emit_memset(vcode_reg_t ptr, vcode_reg_t value, vcode_reg_t len); void emit_case(vcode_reg_t value, vcode_block_t def, const vcode_reg_t *cases, const vcode_block_t *blocks, int ncases); -vcode_reg_t emit_endfile(vcode_reg_t file); void emit_file_open(vcode_reg_t file, vcode_reg_t name, vcode_reg_t length, vcode_reg_t kind, vcode_reg_t status); void emit_file_write(vcode_reg_t file, vcode_reg_t value, vcode_reg_t length); -void emit_file_close(vcode_reg_t file); void emit_file_read(vcode_reg_t file, vcode_reg_t ptr, vcode_reg_t inlen, vcode_reg_t outlen); vcode_reg_t emit_null(vcode_type_t type); diff --git a/test/test_lower.c b/test/test_lower.c index 221b1add..b77bcdc3 100644 --- a/test/test_lower.c +++ b/test/test_lower.c @@ -299,7 +299,6 @@ static void check_bb(int bb, const check_bb_t *expect, int len) case VCODE_OP_SCHED_EVENT: case VCODE_OP_CLEAR_EVENT: case VCODE_OP_FILE_OPEN: - case VCODE_OP_FILE_CLOSE: case VCODE_OP_INDEX_CHECK: case VCODE_OP_RANGE_CHECK: case VCODE_OP_DEBUG_LOCUS: @@ -3891,19 +3890,13 @@ START_TEST(test_closefile) { VCODE_OP_INDEX, .name = "F" }, { VCODE_OP_CONST, .value = 1 }, { VCODE_OP_FILE_OPEN }, - { VCODE_OP_LOAD_INDIRECT }, - { VCODE_OP_CMP, .cmp = VCODE_CMP_EQ }, - { VCODE_OP_COND, .target = 2, .target_else = 1 }, + { VCODE_OP_CONTEXT_UPREF, .hops = 0 }, + { VCODE_OP_FCALL, .func = "WORK.FILEPACK.TEST.FILE_CLOSE(" + "23WORK.FILEPACK.TEST.TEXT)$predef" }, + { VCODE_OP_RETURN }, }; CHECK_BB(0); - - EXPECT_BB(1) = { - { VCODE_OP_FILE_CLOSE }, - { VCODE_OP_JUMP, .target = 2 }, - }; - - CHECK_BB(1); } END_TEST -- 2.39.2