📄 i370.c
字号:
and branch on register must be generated. ID is the label number of the label being checked. */intmvs_check_label (id) int id;{ label_node_t *lp; for (lp = label_anchor; lp; lp = lp->label_next) { if (lp->label_id == id) return 1; } return 0;}/* The label list for the current page freed by linking the list onto the free label element chain. */intmvs_free_label (void){ if (label_anchor) { if (free_anchor) label_anchor->label_next = free_anchor; free_anchor = label_anchor; } label_anchor = 0;}/* If the page size limit is reached a new code page is started, and the base register is set to it. This page break point is counted conservatively, most literals that have the same value are collapsed by the assembler. True is returned when a new page is started. FILE is the assembler output file descriptor. CODE is the length, in bytes, of the instruction to be emitted. LIT is the length of the literal to be emitted. */intmvs_check_page (file, code, lit) FILE *file; int code, lit;{ if (file) assembler_source = file; if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH) { fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num); fprintf (assembler_source, "\tDS\t0F\n"); fprintf (assembler_source, "\tLTORG\n"); fprintf (assembler_source, "\tDS\t0F\n"); fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num); fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER); mvs_page_num++; fprintf (assembler_source, "\tBALR\t%d,0\n", BASE_REGISTER); fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num); fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER); mvs_free_label (); mvs_page_code = code; mvs_page_lit = lit; return 1; } mvs_page_code += code; mvs_page_lit += lit; return 0;}/* Check for C/370 runtime function, they don't use standard calling conventions. True is returned if the function is in the table. NAME is the name of the current function. */intmvs_function_check (name) char *name;{ int lower, middle, upper; int i; lower = 0; upper = MVS_FUNCTION_TABLE_LENGTH - 1; while (lower <= upper) { middle = (lower + upper) / 2; i = strcmp (name, mvs_function_table[middle]); if (i == 0) return 1; if (i < 0) upper = middle - 1; else lower = middle + 1; } return 0;}/* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction. OP is the current operation. MODE is the current operation mode. */ints_operand (op, mode) register rtx op; enum machine_mode mode;{ extern int volatile_ok; register enum rtx_code code = GET_CODE (op); if (CONSTANT_ADDRESS_P (op)) return 1; if (mode == VOIDmode || GET_MODE (op) != mode) return 0; if (code == MEM) { register rtx x = XEXP (op, 0); if (!volatile_ok && op->volatil) return 0; if (REG_P (x) && REG_OK_FOR_BASE_P (x)) return 1; if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (x, 1)) < 4096) return 1; } return 0;}/* Return 1 if OP is a valid R or S operand for an RS, SI or SS type instruction. OP is the current operation. MODE is the current operation mode. */intr_or_s_operand (op, mode) register rtx op; enum machine_mode mode;{ extern int volatile_ok; register enum rtx_code code = GET_CODE (op); if (CONSTANT_ADDRESS_P (op)) return 1; if (mode == VOIDmode || GET_MODE (op) != mode) return 0; if (code == REG) return 1; else if (code == MEM) { register rtx x = XEXP (op, 0); if (!volatile_ok && op->volatil) return 0; if (REG_P (x) && REG_OK_FOR_BASE_P (x)) return 1; if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (x, 1)) < 4096) return 1; } return 0;}/* Return 1 if the next instruction is an unsigned jump instruction. INSN is the current instruction. */unsigned_jump_follows_p (insn) register rtx insn;{ insn = NEXT_INSN (insn); if (GET_CODE (insn) != JUMP_INSN) return 0; insn = XEXP (insn, 3); if (GET_CODE (insn) != SET) return 0; if (GET_CODE (XEXP (insn, 0)) != PC) return 0; insn = XEXP (insn, 1); if (GET_CODE (insn) != IF_THEN_ELSE) return 0; insn = XEXP (insn, 0); return GET_CODE (insn) != GE && GET_CODE (insn) != GT && GET_CODE (insn) != LE && GET_CODE (insn) != LT;}voidi370_function_prolog (f, l) FILE *f; int l;{#if MACROPROLOGUE == 1 fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n", STACK_POINTER_OFFSET + l - 120 + current_function_outgoing_args_size, BASE_REGISTER); fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num ); fprintf (f, "\tLR\t11,1\n"); fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num); mvs_page_code = 6; mvs_page_lit = 4; mvs_check_page (f, 0, 0); function_base_page = mvs_page_num;#else /* MACROPROLOGUE != 1 */ static int function_label_index = 1; static int function_first = 0; static int function_year, function_month, function_day; static int function_hour, function_minute, function_second; int i; if (!function_first) { struct tm *function_time; time_t lcltime; time (&lcltime); function_time = localtime (&lcltime); function_year = function_time->tm_year + 1900; function_month = function_time->tm_mon + 1; function_day = function_time->tm_mday; function_hour = function_time->tm_hour; function_minute = function_time->tm_min; function_second = function_time->tm_sec; fprintf (f, "PPA2\tDS\t0F\n"); fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n"); fprintf (f, "\tDC\tV(CEESTART),A(0)\n"); fprintf (f, "\tDC\tA(CEETIMES)\n"); fprintf (f, "CEETIMES\tDS\t0F\n"); fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n", function_year, function_month, function_day, function_hour, function_minute, function_second); fprintf (f, "\tDC\tCL2'01',CL4'0100'\n"); } fprintf (f, "$DSD%03d\tDSECT\n", function_label_index); fprintf (f, "\tDS\tD\n"); fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l + current_function_outgoing_args_size); fprintf (f, "\tORG\t$DSD%03d\n", function_label_index); fprintf (f, "\tDS\tCL(120+8)\n"); fprintf (f, "\tORG\n"); fprintf (f, "\tDS\t0D\n"); fprintf (f, "$DSL%03d\tEQU\t*-$DSD%03d-8\n", function_label_index, function_label_index); fprintf (f, "\tDS\t0H\n"); assemble_name (f, mvs_function_name); fprintf (f, "\tEQU\t*\n"); fprintf (f, "\tUSING\t*,15\n"); fprintf (f, "\tB\tFPL%03d\n", function_label_index); fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1); fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n"); fprintf (f, "\tDC\tAL4(PPA2)\n"); fprintf (f, "\tDC\tAL4(0)\n"); fprintf (f, "\tDC\tAL4($DSL%03d)\n", function_label_index); fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1); fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name), mvs_function_name); fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index); fprintf (f, "\tSTM\t14,12,12(13)\n"); fprintf (f, "\tL\t2,76(,13)\n"); fprintf (f, "\tL\t0,16(,15)\n"); fprintf (f, "\tALR\t0,2\n"); fprintf (f, "\tCL\t0,12(,12)\n"); fprintf (f, "\tBNH\t*+10\n"); fprintf (f, "\tL\t15,116(,12)\n"); fprintf (f, "\tBALR\t14,15\n"); fprintf (f, "\tL\t15,72(,13)\n"); fprintf (f, "\tSTM\t15,0,72(2)\n"); fprintf (f, "\tMVI\t0(2),X'10'\n"); fprintf (f, "\tST\t2,8(,13)\n "); fprintf (f, "\tST\t13,4(,2)\n "); fprintf (f, "\tLR\t13,2\n"); fprintf (f, "\tDROP\t15\n"); fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER); fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num ); fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER); fprintf (f, "\tLR\t11,1\n"); fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num); mvs_page_code = 4; mvs_page_lit = 4; mvs_check_page (f, 0, 0); function_base_page = mvs_page_num; function_first = 1; function_label_index += 2;#endif /* MACROPROLOGUE */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -