📄 i370.c
字号:
if (GET_CODE (tmp_insn) != IF_THEN_ELSE) continue; /* if we got to here, this instruction is a jump. Is it signed? */ tmp_insn = XEXP (tmp_insn, 0); coda = GET_CODE (tmp_insn); return coda != GE && coda != GT && coda != LE && coda != LT; }}#ifdef TARGET_HLASM/* Target hook for assembling integer objects. This version handles all objects when TARGET_HLASM is defined. */static booli370_hlasm_assemble_integer (x, size, aligned_p) rtx x; unsigned int size; int aligned_p;{ const char *int_format = NULL; if (aligned_p) switch (size) { case 1: int_format = "\tDC\tX'%02X'\n"; break; case 2: int_format = "\tDC\tX'%04X'\n"; break; case 4: if (GET_CODE (x) == CONST_INT) { fputs ("\tDC\tF'", asm_out_file); output_addr_const (asm_out_file, x); fputs ("'\n", asm_out_file); } else { fputs ("\tDC\tA(", asm_out_file); output_addr_const (asm_out_file, x); fputs (")\n", asm_out_file); } return true; } if (int_format && GET_CODE (x) == CONST_INT) { fprintf (asm_out_file, int_format, INTVAL (x)); return true; } return default_assemble_integer (x, size, aligned_p);}/* Generate the assembly code for function entry. FILE is a stdio stream to output the code to. SIZE is an int: how many units of temporary storage to allocate. Refer to the array `regs_ever_live' to determine which registers to save; `regs_ever_live[I]' is nonzero if register number I is ever used in the function. This function is responsible for knowing which registers should not be saved even if used. */static voidi370_output_function_prologue (f, l) FILE *f; HOST_WIDE_INT l;{#if MACROPROLOGUE == 1 fprintf (f, "* Function %s prologue\n", mvs_function_name); fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n", STACK_POINTER_OFFSET + l - 120 + current_function_outgoing_args_size, BASE_REGISTER);#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;#if defined(LE370) 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, "* Function %s prologue\n", mvs_function_name); fprintf (f, "FDSE%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\tFDSE%03d\n", function_label_index); fprintf (f, "\tDS\tCL(120+8)\n"); fprintf (f, "\tORG\n"); fprintf (f, "\tDS\t0D\n"); fprintf (f, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index, function_label_index); fprintf (f, "\tDS\t0H\n"); assemble_name (f, mvs_function_name); fprintf (f, "\tCSECT\n"); fprintf (f, "\tUSING\t*,15\n"); fprintf (f, "\tB\tFENT%03d\n", function_label_index); fprintf (f, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index); fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n"); fprintf (f, "\tDC\tAL4(FPPA%03d)\n", function_label_index); fprintf (f, "\tDC\tAL4(0)\n"); fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index); fprintf (f, "FNAM%03d\tEQU\t*\n", function_label_index); fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name), mvs_function_name); fprintf (f, "FPPA%03d\tDS\t0F\n", function_label_index); fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n"); fprintf (f, "\tDC\tV(CEESTART)\n"); fprintf (f, "\tDC\tAL4(0)\n"); fprintf (f, "\tDC\tAL4(FTIM%03d)\n", function_label_index); fprintf (f, "FTIM%03d\tDS\t0F\n", function_label_index); fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n", function_year, function_month, function_day, function_hour, function_minute); fprintf (f, "\tDC\tCL2'01',CL4'0100'\n"); fprintf (f, "FENT%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, "\tUSING\t*,%d\n", BASE_REGISTER); function_first = 1; function_label_index ++;#else /* !LE370 */ 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, "* Function %s prologue\n", mvs_function_name); fprintf (f, "FDSD%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\tFDSD%03d\n", function_label_index); fprintf (f, "\tDS\tCL(120+8)\n"); fprintf (f, "\tORG\n"); fprintf (f, "\tDS\t0D\n"); fprintf (f, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index, function_label_index); fprintf (f, "\tDS\t0H\n"); assemble_name (f, mvs_function_name); fprintf (f, "\tCSECT\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(FDSL%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, "\tUSING\t*,%d\n", BASE_REGISTER); function_first = 1; function_label_index += 2;#endif /* !LE370 */#endif /* MACROPROLOGUE */ 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); fprintf (f, "* Function %s code\n", mvs_function_name); mvs_free_label_list (); mvs_page_code = 6; mvs_page_lit = 4; mvs_check_page (f, 0, 0); function_base_page = mvs_page_num; /* find all labels in this routine */ i370_label_scan ();}static voidi370_globalize_label (stream, name) FILE *stream; const char *name;{ char temp[MAX_MVS_LABEL_SIZE + 1]; if (mvs_check_alias (name, temp) == 2) fprintf (stream, "%s\tALIAS\tC'%s'\n", temp, name); fputs ("\tENTRY\t", stream); assemble_name (stream, name); putc ('\n', stream);}#endif /* TARGET_HLASM */#ifdef TARGET_ELF_ABI/* The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog. It implements a stack that grows downward. It performs the following steps: -- saves the callers non-volatile registers on the callers stack. -- subtracts stackframe size from the stack pointer. -- stores backpointer to old caller stack. XXX hack alert -- if the global var int leaf_function is nonzero, then this is a leaf, and it might be possible to optimize the prologue into doing even less, e.g. not grabbing a new stackframe or maybe just a partial stack frame. XXX hack alert -- the current stack frame is bloated into twice the needed size by unused entries. These entries make it marginally compatible with MVS/OE/USS C environment, but really they're not used and could probably chopped out. Modifications to i370.md would be needed also, to quite using addresses 136, 140, etc. */static voidi370_output_function_prologue (f, frame_size) FILE *f; HOST_WIDE_INT frame_size;{ static int function_label_index = 1; static int function_first = 0; int stackframe_size, aligned_size; fprintf (f, "# Function prologue\n"); /* define the stack, put it into its own data segment FDSE == Function Stack Entry FDSL == Function Stack Length */ stackframe_size = STACK_POINTER_OFFSET + current_function_outgoing_args_size + frame_size; aligned_size = (stackframe_size + 7) >> 3; aligned_size <<= 3; fprintf (f, "# arg_size=0x%x frame_size=0x%x aligned size=0x%x\n", current_function_outgoing_args_size, frame_size, aligned_size); fprintf (f, "\t.using\t.,r15\n"); /* Branch to exectuable part of prologue. */ fprintf (f, "\tB\t.LFENT%03d\n", function_label_index); /* write the length of the stackframe */ fprintf (f, "\t.long\t%d\n", aligned_size); /* FENT == function prologue entry */ fprintf (f, "\t.balign 2\n.LFENT%03d:\n", function_label_index); /* store multiple registers 14,15,0,...12 at 12 bytes from sp */ fprintf (f, "\tSTM\tr14,r12,12(sp)\n"); /* r3 == saved callee stack pointer */ fprintf (f, "\tLR\tr3,sp\n"); /* 4(r15) == stackframe size */ fprintf (f, "\tSL\tsp,4(,r15)\n"); /* r11 points to arg list in callers stackframe; was passed in r2 */ fprintf (f, "\tLR\tr11,r2\n"); /* store callee stack pointer at 8(sp) */ /* fprintf (f, "\tST\tsp,8(,r3)\n "); wasted cycles, no one uses this ... */ /* backchain -- store caller sp at 4(callee_sp) */ fprintf (f, "\tST\tr3,4(,sp)\n "); fprintf (f, "\t.drop\tr15\n"); /* Place contents of the PSW into r3 that is, place the address of "." into r3 */ fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER); fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER); function_first = 1; function_label_index ++; fprintf (f, ".LPG%d:\n", mvs_page_num ); fprintf (f, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER, mvs_page_num); fprintf (f, "# Function code\n"); mvs_free_label_list (); mvs_page_code = 6; mvs_page_lit = 4; mvs_check_page (f, 0, 0); function_base_page = mvs_page_num; /* find all labels in this routine */ i370_label_scan ();}#endif /* TARGET_ELF_ABI *//* This function generates the assembly code for function exit. Args are as for output_function_prologue (). The function epilogue should not depend on the current stack pointer! It should use the frame pointer only. This is mandatory because of alloca; we also take advantage of it to omit stack adjustments before returning. */static voidi370_output_function_epilogue (file, l) FILE *file; HOST_WIDE_INT l ATTRIBUTE_UNUSED;{ int i; check_label_emit (); mvs_check_page (file, 14, 0); fprintf (file, "* Function %s epilogue\n", mvs_function_name); mvs_page_num++;#if MACROEPILOGUE == 1 fprintf (file, "\tEDCEPIL\n");#else /* MACROEPILOGUE != 1 */ fprintf (file, "\tL\t13,4(,13)\n"); fprintf (file, "\tL\t14,12(,13)\n"); fprintf (file, "\tLM\t2,12,28(13)\n"); fprintf (file, "\tBALR\t1,14\n"); fprintf (file, "\tDC\tA("); assemble_name (file, mvs_function_name); fprintf (file, ")\n" );#endif /* MACROEPILOGUE */ fprintf (file, "* Function %s literal pool\n", mvs_function_name); fprintf (file, "\tDS\t0F\n" ); fprintf (file, "\tLTORG\n"); fprintf (file, "* Function %s page table\n", mvs_function_name); fprintf (file, "\tDS\t0F\n"); fprintf (file, "PGT%d\tEQU\t*\n", function_base_page); mvs_free_label_list(); for (i = function_base_page; i < mvs_page_num; i++) fprintf (file, "\tDC\tA(PG%d)\n", i);}/* Mark external references. */static voidi370_encode_section_info (decl, first) tree decl; int first ATTRIBUTE_UNUSED;{ if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -