reg-stack.c revision 18334
118334Speter/* Register to Stack convert for GNU compiler. 218334Speter Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 318334Speter 418334SpeterThis file is part of GNU CC. 518334Speter 618334SpeterGNU CC is free software; you can redistribute it and/or modify 718334Speterit under the terms of the GNU General Public License as published by 818334Speterthe Free Software Foundation; either version 2, or (at your option) 918334Speterany later version. 1018334Speter 1118334SpeterGNU CC is distributed in the hope that it will be useful, 1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1418334SpeterGNU General Public License for more details. 1518334Speter 1618334SpeterYou should have received a copy of the GNU General Public License 1718334Speteralong with GNU CC; see the file COPYING. If not, write to 1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 1918334SpeterBoston, MA 02111-1307, USA. */ 2018334Speter 2118334Speter/* This pass converts stack-like registers from the "flat register 2218334Speter file" model that gcc uses, to a stack convention that the 387 uses. 2318334Speter 2418334Speter * The form of the input: 2518334Speter 2618334Speter On input, the function consists of insn that have had their 2718334Speter registers fully allocated to a set of "virtual" registers. Note that 2818334Speter the word "virtual" is used differently here than elsewhere in gcc: for 2918334Speter each virtual stack reg, there is a hard reg, but the mapping between 3018334Speter them is not known until this pass is run. On output, hard register 3118334Speter numbers have been substituted, and various pop and exchange insns have 3218334Speter been emitted. The hard register numbers and the virtual register 3318334Speter numbers completely overlap - before this pass, all stack register 3418334Speter numbers are virtual, and afterward they are all hard. 3518334Speter 3618334Speter The virtual registers can be manipulated normally by gcc, and their 3718334Speter semantics are the same as for normal registers. After the hard 3818334Speter register numbers are substituted, the semantics of an insn containing 3918334Speter stack-like regs are not the same as for an insn with normal regs: for 4018334Speter instance, it is not safe to delete an insn that appears to be a no-op 4118334Speter move. In general, no insn containing hard regs should be changed 4218334Speter after this pass is done. 4318334Speter 4418334Speter * The form of the output: 4518334Speter 4618334Speter After this pass, hard register numbers represent the distance from 4718334Speter the current top of stack to the desired register. A reference to 4818334Speter FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1, 4918334Speter represents the register just below that, and so forth. Also, REG_DEAD 5018334Speter notes indicate whether or not a stack register should be popped. 5118334Speter 5218334Speter A "swap" insn looks like a parallel of two patterns, where each 5318334Speter pattern is a SET: one sets A to B, the other B to A. 5418334Speter 5518334Speter A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG 5618334Speter and whose SET_DEST is REG or MEM. Any other SET_DEST, such as PLUS, 5718334Speter will replace the existing stack top, not push a new value. 5818334Speter 5918334Speter A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose 6018334Speter SET_SRC is REG or MEM. 6118334Speter 6218334Speter The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG 6318334Speter appears ambiguous. As a special case, the presence of a REG_DEAD note 6418334Speter for FIRST_STACK_REG differentiates between a load insn and a pop. 6518334Speter 6618334Speter If a REG_DEAD is present, the insn represents a "pop" that discards 6718334Speter the top of the register stack. If there is no REG_DEAD note, then the 6818334Speter insn represents a "dup" or a push of the current top of stack onto the 6918334Speter stack. 7018334Speter 7118334Speter * Methodology: 7218334Speter 7318334Speter Existing REG_DEAD and REG_UNUSED notes for stack registers are 7418334Speter deleted and recreated from scratch. REG_DEAD is never created for a 7518334Speter SET_DEST, only REG_UNUSED. 7618334Speter 7718334Speter Before life analysis, the mode of each insn is set based on whether 7818334Speter or not any stack registers are mentioned within that insn. VOIDmode 7918334Speter means that no regs are mentioned anyway, and QImode means that at 8018334Speter least one pattern within the insn mentions stack registers. This 8118334Speter information is valid until after reg_to_stack returns, and is used 8218334Speter from jump_optimize. 8318334Speter 8418334Speter * asm_operands: 8518334Speter 8618334Speter There are several rules on the usage of stack-like regs in 8718334Speter asm_operands insns. These rules apply only to the operands that are 8818334Speter stack-like regs: 8918334Speter 9018334Speter 1. Given a set of input regs that die in an asm_operands, it is 9118334Speter necessary to know which are implicitly popped by the asm, and 9218334Speter which must be explicitly popped by gcc. 9318334Speter 9418334Speter An input reg that is implicitly popped by the asm must be 9518334Speter explicitly clobbered, unless it is constrained to match an 9618334Speter output operand. 9718334Speter 9818334Speter 2. For any input reg that is implicitly popped by an asm, it is 9918334Speter necessary to know how to adjust the stack to compensate for the pop. 10018334Speter If any non-popped input is closer to the top of the reg-stack than 10118334Speter the implicitly popped reg, it would not be possible to know what the 10218334Speter stack looked like - it's not clear how the rest of the stack "slides 10318334Speter up". 10418334Speter 10518334Speter All implicitly popped input regs must be closer to the top of 10618334Speter the reg-stack than any input that is not implicitly popped. 10718334Speter 10818334Speter 3. It is possible that if an input dies in an insn, reload might 10918334Speter use the input reg for an output reload. Consider this example: 11018334Speter 11118334Speter asm ("foo" : "=t" (a) : "f" (b)); 11218334Speter 11318334Speter This asm says that input B is not popped by the asm, and that 11418334Speter the asm pushes a result onto the reg-stack, ie, the stack is one 11518334Speter deeper after the asm than it was before. But, it is possible that 11618334Speter reload will think that it can use the same reg for both the input and 11718334Speter the output, if input B dies in this insn. 11818334Speter 11918334Speter If any input operand uses the "f" constraint, all output reg 12018334Speter constraints must use the "&" earlyclobber. 12118334Speter 12218334Speter The asm above would be written as 12318334Speter 12418334Speter asm ("foo" : "=&t" (a) : "f" (b)); 12518334Speter 12618334Speter 4. Some operands need to be in particular places on the stack. All 12718334Speter output operands fall in this category - there is no other way to 12818334Speter know which regs the outputs appear in unless the user indicates 12918334Speter this in the constraints. 13018334Speter 13118334Speter Output operands must specifically indicate which reg an output 13218334Speter appears in after an asm. "=f" is not allowed: the operand 13318334Speter constraints must select a class with a single reg. 13418334Speter 13518334Speter 5. Output operands may not be "inserted" between existing stack regs. 13618334Speter Since no 387 opcode uses a read/write operand, all output operands 13718334Speter are dead before the asm_operands, and are pushed by the asm_operands. 13818334Speter It makes no sense to push anywhere but the top of the reg-stack. 13918334Speter 14018334Speter Output operands must start at the top of the reg-stack: output 14118334Speter operands may not "skip" a reg. 14218334Speter 14318334Speter 6. Some asm statements may need extra stack space for internal 14418334Speter calculations. This can be guaranteed by clobbering stack registers 14518334Speter unrelated to the inputs and outputs. 14618334Speter 14718334Speter Here are a couple of reasonable asms to want to write. This asm 14818334Speter takes one input, which is internally popped, and produces two outputs. 14918334Speter 15018334Speter asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp)); 15118334Speter 15218334Speter This asm takes two inputs, which are popped by the fyl2xp1 opcode, 15318334Speter and replaces them with one output. The user must code the "st(1)" 15418334Speter clobber for reg-stack.c to know that fyl2xp1 pops both inputs. 15518334Speter 15618334Speter asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)"); 15718334Speter 15818334Speter */ 15918334Speter 16018334Speter#include <stdio.h> 16118334Speter#include "config.h" 16218334Speter#include "tree.h" 16318334Speter#include "rtl.h" 16418334Speter#include "insn-config.h" 16518334Speter#include "regs.h" 16618334Speter#include "hard-reg-set.h" 16718334Speter#include "flags.h" 16818334Speter 16918334Speter#ifdef STACK_REGS 17018334Speter 17118334Speter#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1) 17218334Speter 17318334Speter/* This is the basic stack record. TOP is an index into REG[] such 17418334Speter that REG[TOP] is the top of stack. If TOP is -1 the stack is empty. 17518334Speter 17618334Speter If TOP is -2, REG[] is not yet initialized. Stack initialization 17718334Speter consists of placing each live reg in array `reg' and setting `top' 17818334Speter appropriately. 17918334Speter 18018334Speter REG_SET indicates which registers are live. */ 18118334Speter 18218334Spetertypedef struct stack_def 18318334Speter{ 18418334Speter int top; /* index to top stack element */ 18518334Speter HARD_REG_SET reg_set; /* set of live registers */ 18618334Speter char reg[REG_STACK_SIZE]; /* register - stack mapping */ 18718334Speter} *stack; 18818334Speter 18918334Speter/* highest instruction uid */ 19018334Speterstatic int max_uid = 0; 19118334Speter 19218334Speter/* Number of basic blocks in the current function. */ 19318334Speterstatic int blocks; 19418334Speter 19518334Speter/* Element N is first insn in basic block N. 19618334Speter This info lasts until we finish compiling the function. */ 19718334Speterstatic rtx *block_begin; 19818334Speter 19918334Speter/* Element N is last insn in basic block N. 20018334Speter This info lasts until we finish compiling the function. */ 20118334Speterstatic rtx *block_end; 20218334Speter 20318334Speter/* Element N is nonzero if control can drop into basic block N */ 20418334Speterstatic char *block_drops_in; 20518334Speter 20618334Speter/* Element N says all about the stack at entry block N */ 20718334Speterstatic stack block_stack_in; 20818334Speter 20918334Speter/* Element N says all about the stack life at the end of block N */ 21018334Speterstatic HARD_REG_SET *block_out_reg_set; 21118334Speter 21218334Speter/* This is where the BLOCK_NUM values are really stored. This is set 21318334Speter up by find_blocks and used there and in life_analysis. It can be used 21418334Speter later, but only to look up an insn that is the head or tail of some 21518334Speter block. life_analysis and the stack register conversion process can 21618334Speter add insns within a block. */ 21718334Speterstatic int *block_number; 21818334Speter 21918334Speter/* This is the register file for all register after conversion */ 22018334Speterstatic rtx 22118334Speter FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE]; 22218334Speter 22318334Speter#define FP_MODE_REG(regno,mode) \ 22418334Speter (FP_mode_reg[(regno)-FIRST_STACK_REG][(int)(mode)]) 22518334Speter 22618334Speter/* Get the basic block number of an insn. See note at block_number 22718334Speter definition are validity of this information. */ 22818334Speter 22918334Speter#define BLOCK_NUM(INSN) \ 23018334Speter ((INSN_UID (INSN) > max_uid) \ 23118334Speter ? (abort() , -1) : block_number[INSN_UID (INSN)]) 23218334Speter 23318334Speterextern rtx forced_labels; 23418334Speterextern rtx gen_jump (); 23518334Speterextern rtx gen_movdf (), gen_movxf (); 23618334Speterextern rtx find_regno_note (); 23718334Speterextern rtx emit_jump_insn_before (); 23818334Speterextern rtx emit_label_after (); 23918334Speter 24018334Speter/* Forward declarations */ 24118334Speter 24218334Speterstatic void find_blocks (); 24318334Speterstatic uses_reg_or_mem (); 24418334Speterstatic void stack_reg_life_analysis (); 24518334Speterstatic void record_reg_life_pat (); 24618334Speterstatic void change_stack (); 24718334Speterstatic void convert_regs (); 24818334Speterstatic void dump_stack_info (); 24918334Speter 25018334Speter/* Mark all registers needed for this pattern. */ 25118334Speter 25218334Speterstatic void 25318334Spetermark_regs_pat (pat, set) 25418334Speter rtx pat; 25518334Speter HARD_REG_SET *set; 25618334Speter{ 25718334Speter enum machine_mode mode; 25818334Speter register int regno; 25918334Speter register int count; 26018334Speter 26118334Speter if (GET_CODE (pat) == SUBREG) 26218334Speter { 26318334Speter mode = GET_MODE (pat); 26418334Speter regno = SUBREG_WORD (pat); 26518334Speter regno += REGNO (SUBREG_REG (pat)); 26618334Speter } 26718334Speter else 26818334Speter regno = REGNO (pat), mode = GET_MODE (pat); 26918334Speter 27018334Speter for (count = HARD_REGNO_NREGS (regno, mode); 27118334Speter count; count--, regno++) 27218334Speter SET_HARD_REG_BIT (*set, regno); 27318334Speter} 27418334Speter 27518334Speter/* Reorganise the stack into ascending numbers, 27618334Speter after this insn. */ 27718334Speter 27818334Speterstatic void 27918334Speterstraighten_stack (insn, regstack) 28018334Speter rtx insn; 28118334Speter stack regstack; 28218334Speter{ 28318334Speter struct stack_def temp_stack; 28418334Speter int top; 28518334Speter 28618334Speter temp_stack.reg_set = regstack->reg_set; 28718334Speter 28818334Speter for (top = temp_stack.top = regstack->top; top >= 0; top--) 28918334Speter temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top; 29018334Speter 29118334Speter change_stack (insn, regstack, &temp_stack, emit_insn_after); 29218334Speter} 29318334Speter 29418334Speter/* Return non-zero if any stack register is mentioned somewhere within PAT. */ 29518334Speter 29618334Speterint 29718334Speterstack_regs_mentioned_p (pat) 29818334Speter rtx pat; 29918334Speter{ 30018334Speter register char *fmt; 30118334Speter register int i; 30218334Speter 30318334Speter if (STACK_REG_P (pat)) 30418334Speter return 1; 30518334Speter 30618334Speter fmt = GET_RTX_FORMAT (GET_CODE (pat)); 30718334Speter for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) 30818334Speter { 30918334Speter if (fmt[i] == 'E') 31018334Speter { 31118334Speter register int j; 31218334Speter 31318334Speter for (j = XVECLEN (pat, i) - 1; j >= 0; j--) 31418334Speter if (stack_regs_mentioned_p (XVECEXP (pat, i, j))) 31518334Speter return 1; 31618334Speter } 31718334Speter else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i))) 31818334Speter return 1; 31918334Speter } 32018334Speter 32118334Speter return 0; 32218334Speter} 32318334Speter 32418334Speter/* Convert register usage from "flat" register file usage to a "stack 32518334Speter register file. FIRST is the first insn in the function, FILE is the 32618334Speter dump file, if used. 32718334Speter 32818334Speter First compute the beginning and end of each basic block. Do a 32918334Speter register life analysis on the stack registers, recording the result 33018334Speter for the head and tail of each basic block. The convert each insn one 33118334Speter by one. Run a last jump_optimize() pass, if optimizing, to eliminate 33218334Speter any cross-jumping created when the converter inserts pop insns.*/ 33318334Speter 33418334Spetervoid 33518334Speterreg_to_stack (first, file) 33618334Speter rtx first; 33718334Speter FILE *file; 33818334Speter{ 33918334Speter register rtx insn; 34018334Speter register int i; 34118334Speter int stack_reg_seen = 0; 34218334Speter enum machine_mode mode; 34318334Speter HARD_REG_SET stackentry; 34418334Speter 34518334Speter CLEAR_HARD_REG_SET (stackentry); 34618334Speter 34718334Speter { 34818334Speter static initialised; 34918334Speter if (!initialised) 35018334Speter { 35118334Speter#if 0 35218334Speter initialised = 1; /* This array can not have been previously 35318334Speter initialised, because the rtx's are 35418334Speter thrown away between compilations of 35518334Speter functions. */ 35618334Speter#endif 35718334Speter for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) 35818334Speter { 35918334Speter for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode; 36018334Speter mode = GET_MODE_WIDER_MODE (mode)) 36118334Speter FP_MODE_REG (i, mode) = gen_rtx (REG, mode, i); 36218334Speter for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT); mode != VOIDmode; 36318334Speter mode = GET_MODE_WIDER_MODE (mode)) 36418334Speter FP_MODE_REG (i, mode) = gen_rtx (REG, mode, i); 36518334Speter } 36618334Speter } 36718334Speter } 36818334Speter 36918334Speter /* Count the basic blocks. Also find maximum insn uid. */ 37018334Speter { 37118334Speter register RTX_CODE prev_code = BARRIER; 37218334Speter register RTX_CODE code; 37318334Speter register before_function_beg = 1; 37418334Speter 37518334Speter max_uid = 0; 37618334Speter blocks = 0; 37718334Speter for (insn = first; insn; insn = NEXT_INSN (insn)) 37818334Speter { 37918334Speter /* Note that this loop must select the same block boundaries 38018334Speter as code in find_blocks. Also note that this code is not the 38118334Speter same as that used in flow.c. */ 38218334Speter 38318334Speter if (INSN_UID (insn) > max_uid) 38418334Speter max_uid = INSN_UID (insn); 38518334Speter 38618334Speter code = GET_CODE (insn); 38718334Speter 38818334Speter if (code == CODE_LABEL 38918334Speter || (prev_code != INSN 39018334Speter && prev_code != CALL_INSN 39118334Speter && prev_code != CODE_LABEL 39218334Speter && GET_RTX_CLASS (code) == 'i')) 39318334Speter blocks++; 39418334Speter 39518334Speter if (code == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG) 39618334Speter before_function_beg = 0; 39718334Speter 39818334Speter /* Remember whether or not this insn mentions an FP regs. 39918334Speter Check JUMP_INSNs too, in case someone creates a funny PARALLEL. */ 40018334Speter 40118334Speter if (GET_RTX_CLASS (code) == 'i' 40218334Speter && stack_regs_mentioned_p (PATTERN (insn))) 40318334Speter { 40418334Speter stack_reg_seen = 1; 40518334Speter PUT_MODE (insn, QImode); 40618334Speter 40718334Speter /* Note any register passing parameters. */ 40818334Speter 40918334Speter if (before_function_beg && code == INSN 41018334Speter && GET_CODE (PATTERN (insn)) == USE) 41118334Speter record_reg_life_pat (PATTERN (insn), (HARD_REG_SET*) 0, 41218334Speter &stackentry, 1); 41318334Speter } 41418334Speter else 41518334Speter PUT_MODE (insn, VOIDmode); 41618334Speter 41718334Speter if (code == CODE_LABEL) 41818334Speter LABEL_REFS (insn) = insn; /* delete old chain */ 41918334Speter 42018334Speter if (code != NOTE) 42118334Speter prev_code = code; 42218334Speter } 42318334Speter } 42418334Speter 42518334Speter /* If no stack register reference exists in this insn, there isn't 42618334Speter anything to convert. */ 42718334Speter 42818334Speter if (! stack_reg_seen) 42918334Speter return; 43018334Speter 43118334Speter /* If there are stack registers, there must be at least one block. */ 43218334Speter 43318334Speter if (! blocks) 43418334Speter abort (); 43518334Speter 43618334Speter /* Allocate some tables that last till end of compiling this function 43718334Speter and some needed only in find_blocks and life_analysis. */ 43818334Speter 43918334Speter block_begin = (rtx *) alloca (blocks * sizeof (rtx)); 44018334Speter block_end = (rtx *) alloca (blocks * sizeof (rtx)); 44118334Speter block_drops_in = (char *) alloca (blocks); 44218334Speter 44318334Speter block_stack_in = (stack) alloca (blocks * sizeof (struct stack_def)); 44418334Speter block_out_reg_set = (HARD_REG_SET *) alloca (blocks * sizeof (HARD_REG_SET)); 44518334Speter bzero ((char *) block_stack_in, blocks * sizeof (struct stack_def)); 44618334Speter bzero ((char *) block_out_reg_set, blocks * sizeof (HARD_REG_SET)); 44718334Speter 44818334Speter block_number = (int *) alloca ((max_uid + 1) * sizeof (int)); 44918334Speter 45018334Speter find_blocks (first); 45118334Speter stack_reg_life_analysis (first, &stackentry); 45218334Speter 45318334Speter /* Dump the life analysis debug information before jump 45418334Speter optimization, as that will destroy the LABEL_REFS we keep the 45518334Speter information in. */ 45618334Speter 45718334Speter if (file) 45818334Speter dump_stack_info (file); 45918334Speter 46018334Speter convert_regs (); 46118334Speter 46218334Speter if (optimize) 46318334Speter jump_optimize (first, 2, 0, 0); 46418334Speter} 46518334Speter 46618334Speter/* Check PAT, which is in INSN, for LABEL_REFs. Add INSN to the 46718334Speter label's chain of references, and note which insn contains each 46818334Speter reference. */ 46918334Speter 47018334Speterstatic void 47118334Speterrecord_label_references (insn, pat) 47218334Speter rtx insn, pat; 47318334Speter{ 47418334Speter register enum rtx_code code = GET_CODE (pat); 47518334Speter register int i; 47618334Speter register char *fmt; 47718334Speter 47818334Speter if (code == LABEL_REF) 47918334Speter { 48018334Speter register rtx label = XEXP (pat, 0); 48118334Speter register rtx ref; 48218334Speter 48318334Speter if (GET_CODE (label) != CODE_LABEL) 48418334Speter abort (); 48518334Speter 48618334Speter /* Don't make a duplicate in the code_label's chain. */ 48718334Speter 48818334Speter for (ref = LABEL_REFS (label); 48918334Speter ref && ref != label; 49018334Speter ref = LABEL_NEXTREF (ref)) 49118334Speter if (CONTAINING_INSN (ref) == insn) 49218334Speter return; 49318334Speter 49418334Speter CONTAINING_INSN (pat) = insn; 49518334Speter LABEL_NEXTREF (pat) = LABEL_REFS (label); 49618334Speter LABEL_REFS (label) = pat; 49718334Speter 49818334Speter return; 49918334Speter } 50018334Speter 50118334Speter fmt = GET_RTX_FORMAT (code); 50218334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 50318334Speter { 50418334Speter if (fmt[i] == 'e') 50518334Speter record_label_references (insn, XEXP (pat, i)); 50618334Speter if (fmt[i] == 'E') 50718334Speter { 50818334Speter register int j; 50918334Speter for (j = 0; j < XVECLEN (pat, i); j++) 51018334Speter record_label_references (insn, XVECEXP (pat, i, j)); 51118334Speter } 51218334Speter } 51318334Speter} 51418334Speter 51518334Speter/* Return a pointer to the REG expression within PAT. If PAT is not a 51618334Speter REG, possible enclosed by a conversion rtx, return the inner part of 51718334Speter PAT that stopped the search. */ 51818334Speter 51918334Speterstatic rtx * 52018334Speterget_true_reg (pat) 52118334Speter rtx *pat; 52218334Speter{ 52318334Speter for (;;) 52418334Speter switch (GET_CODE (*pat)) 52518334Speter { 52618334Speter case SUBREG: 52718334Speter /* eliminate FP subregister accesses in favour of the 52818334Speter actual FP register in use. */ 52918334Speter { 53018334Speter rtx subreg; 53118334Speter if (FP_REG_P (subreg = SUBREG_REG (*pat))) 53218334Speter { 53318334Speter *pat = FP_MODE_REG (REGNO (subreg) + SUBREG_WORD (*pat), 53418334Speter GET_MODE (subreg)); 53518334Speter default: 53618334Speter return pat; 53718334Speter } 53818334Speter } 53918334Speter case FLOAT: 54018334Speter case FIX: 54118334Speter case FLOAT_EXTEND: 54218334Speter pat = & XEXP (*pat, 0); 54318334Speter } 54418334Speter} 54518334Speter 54618334Speter/* Scan the OPERANDS and OPERAND_CONSTRAINTS of an asm_operands. 54718334Speter N_OPERANDS is the total number of operands. Return which alternative 54818334Speter matched, or -1 is no alternative matches. 54918334Speter 55018334Speter OPERAND_MATCHES is an array which indicates which operand this 55118334Speter operand matches due to the constraints, or -1 if no match is required. 55218334Speter If two operands match by coincidence, but are not required to match by 55318334Speter the constraints, -1 is returned. 55418334Speter 55518334Speter OPERAND_CLASS is an array which indicates the smallest class 55618334Speter required by the constraints. If the alternative that matches calls 55718334Speter for some class `class', and the operand matches a subclass of `class', 55818334Speter OPERAND_CLASS is set to `class' as required by the constraints, not to 55918334Speter the subclass. If an alternative allows more than one class, 56018334Speter OPERAND_CLASS is set to the smallest class that is a union of the 56118334Speter allowed classes. */ 56218334Speter 56318334Speterstatic int 56418334Speterconstrain_asm_operands (n_operands, operands, operand_constraints, 56518334Speter operand_matches, operand_class) 56618334Speter int n_operands; 56718334Speter rtx *operands; 56818334Speter char **operand_constraints; 56918334Speter int *operand_matches; 57018334Speter enum reg_class *operand_class; 57118334Speter{ 57218334Speter char **constraints = (char **) alloca (n_operands * sizeof (char *)); 57318334Speter char *q; 57418334Speter int this_alternative, this_operand; 57518334Speter int n_alternatives; 57618334Speter int j; 57718334Speter 57818334Speter for (j = 0; j < n_operands; j++) 57918334Speter constraints[j] = operand_constraints[j]; 58018334Speter 58118334Speter /* Compute the number of alternatives in the operands. reload has 58218334Speter already guaranteed that all operands have the same number of 58318334Speter alternatives. */ 58418334Speter 58518334Speter n_alternatives = 1; 58618334Speter for (q = constraints[0]; *q; q++) 58718334Speter n_alternatives += (*q == ','); 58818334Speter 58918334Speter this_alternative = 0; 59018334Speter while (this_alternative < n_alternatives) 59118334Speter { 59218334Speter int lose = 0; 59318334Speter int i; 59418334Speter 59518334Speter /* No operands match, no narrow class requirements yet. */ 59618334Speter for (i = 0; i < n_operands; i++) 59718334Speter { 59818334Speter operand_matches[i] = -1; 59918334Speter operand_class[i] = NO_REGS; 60018334Speter } 60118334Speter 60218334Speter for (this_operand = 0; this_operand < n_operands; this_operand++) 60318334Speter { 60418334Speter rtx op = operands[this_operand]; 60518334Speter enum machine_mode mode = GET_MODE (op); 60618334Speter char *p = constraints[this_operand]; 60718334Speter int offset = 0; 60818334Speter int win = 0; 60918334Speter int c; 61018334Speter 61118334Speter if (GET_CODE (op) == SUBREG) 61218334Speter { 61318334Speter if (GET_CODE (SUBREG_REG (op)) == REG 61418334Speter && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER) 61518334Speter offset = SUBREG_WORD (op); 61618334Speter op = SUBREG_REG (op); 61718334Speter } 61818334Speter 61918334Speter /* An empty constraint or empty alternative 62018334Speter allows anything which matched the pattern. */ 62118334Speter if (*p == 0 || *p == ',') 62218334Speter win = 1; 62318334Speter 62418334Speter while (*p && (c = *p++) != ',') 62518334Speter switch (c) 62618334Speter { 62718334Speter case '=': 62818334Speter case '+': 62918334Speter case '?': 63018334Speter case '&': 63118334Speter case '!': 63218334Speter case '*': 63318334Speter case '%': 63418334Speter /* Ignore these. */ 63518334Speter break; 63618334Speter 63718334Speter case '#': 63818334Speter /* Ignore rest of this alternative. */ 63918334Speter while (*p && *p != ',') p++; 64018334Speter break; 64118334Speter 64218334Speter case '0': 64318334Speter case '1': 64418334Speter case '2': 64518334Speter case '3': 64618334Speter case '4': 64718334Speter case '5': 64818334Speter /* This operand must be the same as a previous one. 64918334Speter This kind of constraint is used for instructions such 65018334Speter as add when they take only two operands. 65118334Speter 65218334Speter Note that the lower-numbered operand is passed first. */ 65318334Speter 65418334Speter if (operands_match_p (operands[c - '0'], 65518334Speter operands[this_operand])) 65618334Speter { 65718334Speter operand_matches[this_operand] = c - '0'; 65818334Speter win = 1; 65918334Speter } 66018334Speter break; 66118334Speter 66218334Speter case 'p': 66318334Speter /* p is used for address_operands. Since this is an asm, 66418334Speter just to make sure that the operand is valid for Pmode. */ 66518334Speter 66618334Speter if (strict_memory_address_p (Pmode, op)) 66718334Speter win = 1; 66818334Speter break; 66918334Speter 67018334Speter case 'g': 67118334Speter /* Anything goes unless it is a REG and really has a hard reg 67218334Speter but the hard reg is not in the class GENERAL_REGS. */ 67318334Speter if (GENERAL_REGS == ALL_REGS 67418334Speter || GET_CODE (op) != REG 67518334Speter || reg_fits_class_p (op, GENERAL_REGS, offset, mode)) 67618334Speter { 67718334Speter if (GET_CODE (op) == REG) 67818334Speter operand_class[this_operand] 67918334Speter = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS]; 68018334Speter win = 1; 68118334Speter } 68218334Speter break; 68318334Speter 68418334Speter case 'r': 68518334Speter if (GET_CODE (op) == REG 68618334Speter && (GENERAL_REGS == ALL_REGS 68718334Speter || reg_fits_class_p (op, GENERAL_REGS, offset, mode))) 68818334Speter { 68918334Speter operand_class[this_operand] 69018334Speter = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS]; 69118334Speter win = 1; 69218334Speter } 69318334Speter break; 69418334Speter 69518334Speter case 'X': 69618334Speter /* This is used for a MATCH_SCRATCH in the cases when we 69718334Speter don't actually need anything. So anything goes any time. */ 69818334Speter win = 1; 69918334Speter break; 70018334Speter 70118334Speter case 'm': 70218334Speter if (GET_CODE (op) == MEM) 70318334Speter win = 1; 70418334Speter break; 70518334Speter 70618334Speter case '<': 70718334Speter if (GET_CODE (op) == MEM 70818334Speter && (GET_CODE (XEXP (op, 0)) == PRE_DEC 70918334Speter || GET_CODE (XEXP (op, 0)) == POST_DEC)) 71018334Speter win = 1; 71118334Speter break; 71218334Speter 71318334Speter case '>': 71418334Speter if (GET_CODE (op) == MEM 71518334Speter && (GET_CODE (XEXP (op, 0)) == PRE_INC 71618334Speter || GET_CODE (XEXP (op, 0)) == POST_INC)) 71718334Speter win = 1; 71818334Speter break; 71918334Speter 72018334Speter case 'E': 72118334Speter /* Match any CONST_DOUBLE, but only if 72218334Speter we can examine the bits of it reliably. */ 72318334Speter if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT 72418334Speter || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD) 72518334Speter && GET_CODE (op) != VOIDmode && ! flag_pretend_float) 72618334Speter break; 72718334Speter if (GET_CODE (op) == CONST_DOUBLE) 72818334Speter win = 1; 72918334Speter break; 73018334Speter 73118334Speter case 'F': 73218334Speter if (GET_CODE (op) == CONST_DOUBLE) 73318334Speter win = 1; 73418334Speter break; 73518334Speter 73618334Speter case 'G': 73718334Speter case 'H': 73818334Speter if (GET_CODE (op) == CONST_DOUBLE 73918334Speter && CONST_DOUBLE_OK_FOR_LETTER_P (op, c)) 74018334Speter win = 1; 74118334Speter break; 74218334Speter 74318334Speter case 's': 74418334Speter if (GET_CODE (op) == CONST_INT 74518334Speter || (GET_CODE (op) == CONST_DOUBLE 74618334Speter && GET_MODE (op) == VOIDmode)) 74718334Speter break; 74818334Speter /* Fall through */ 74918334Speter case 'i': 75018334Speter if (CONSTANT_P (op)) 75118334Speter win = 1; 75218334Speter break; 75318334Speter 75418334Speter case 'n': 75518334Speter if (GET_CODE (op) == CONST_INT 75618334Speter || (GET_CODE (op) == CONST_DOUBLE 75718334Speter && GET_MODE (op) == VOIDmode)) 75818334Speter win = 1; 75918334Speter break; 76018334Speter 76118334Speter case 'I': 76218334Speter case 'J': 76318334Speter case 'K': 76418334Speter case 'L': 76518334Speter case 'M': 76618334Speter case 'N': 76718334Speter case 'O': 76818334Speter case 'P': 76918334Speter if (GET_CODE (op) == CONST_INT 77018334Speter && CONST_OK_FOR_LETTER_P (INTVAL (op), c)) 77118334Speter win = 1; 77218334Speter break; 77318334Speter 77418334Speter#ifdef EXTRA_CONSTRAINT 77518334Speter case 'Q': 77618334Speter case 'R': 77718334Speter case 'S': 77818334Speter case 'T': 77918334Speter case 'U': 78018334Speter if (EXTRA_CONSTRAINT (op, c)) 78118334Speter win = 1; 78218334Speter break; 78318334Speter#endif 78418334Speter 78518334Speter case 'V': 78618334Speter if (GET_CODE (op) == MEM && ! offsettable_memref_p (op)) 78718334Speter win = 1; 78818334Speter break; 78918334Speter 79018334Speter case 'o': 79118334Speter if (offsettable_memref_p (op)) 79218334Speter win = 1; 79318334Speter break; 79418334Speter 79518334Speter default: 79618334Speter if (GET_CODE (op) == REG 79718334Speter && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c), 79818334Speter offset, mode)) 79918334Speter { 80018334Speter operand_class[this_operand] 80118334Speter = reg_class_subunion[(int)operand_class[this_operand]][(int) REG_CLASS_FROM_LETTER (c)]; 80218334Speter win = 1; 80318334Speter } 80418334Speter } 80518334Speter 80618334Speter constraints[this_operand] = p; 80718334Speter /* If this operand did not win somehow, 80818334Speter this alternative loses. */ 80918334Speter if (! win) 81018334Speter lose = 1; 81118334Speter } 81218334Speter /* This alternative won; the operands are ok. 81318334Speter Change whichever operands this alternative says to change. */ 81418334Speter if (! lose) 81518334Speter break; 81618334Speter 81718334Speter this_alternative++; 81818334Speter } 81918334Speter 82018334Speter /* For operands constrained to match another operand, copy the other 82118334Speter operand's class to this operand's class. */ 82218334Speter for (j = 0; j < n_operands; j++) 82318334Speter if (operand_matches[j] >= 0) 82418334Speter operand_class[j] = operand_class[operand_matches[j]]; 82518334Speter 82618334Speter return this_alternative == n_alternatives ? -1 : this_alternative; 82718334Speter} 82818334Speter 82918334Speter/* Record the life info of each stack reg in INSN, updating REGSTACK. 83018334Speter N_INPUTS is the number of inputs; N_OUTPUTS the outputs. CONSTRAINTS 83118334Speter is an array of the constraint strings used in the asm statement. 83218334Speter OPERANDS is an array of all operands for the insn, and is assumed to 83318334Speter contain all output operands, then all inputs operands. 83418334Speter 83518334Speter There are many rules that an asm statement for stack-like regs must 83618334Speter follow. Those rules are explained at the top of this file: the rule 83718334Speter numbers below refer to that explanation. */ 83818334Speter 83918334Speterstatic void 84018334Speterrecord_asm_reg_life (insn, regstack, operands, constraints, 84118334Speter n_inputs, n_outputs) 84218334Speter rtx insn; 84318334Speter stack regstack; 84418334Speter rtx *operands; 84518334Speter char **constraints; 84618334Speter int n_inputs, n_outputs; 84718334Speter{ 84818334Speter int i; 84918334Speter int n_operands = n_inputs + n_outputs; 85018334Speter int first_input = n_outputs; 85118334Speter int n_clobbers; 85218334Speter int malformed_asm = 0; 85318334Speter rtx body = PATTERN (insn); 85418334Speter 85518334Speter int *operand_matches = (int *) alloca (n_operands * sizeof (int *)); 85618334Speter 85718334Speter enum reg_class *operand_class 85818334Speter = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *)); 85918334Speter 86018334Speter int reg_used_as_output[FIRST_PSEUDO_REGISTER]; 86118334Speter int implicitly_dies[FIRST_PSEUDO_REGISTER]; 86218334Speter 86318334Speter rtx *clobber_reg; 86418334Speter 86518334Speter /* Find out what the constraints require. If no constraint 86618334Speter alternative matches, this asm is malformed. */ 86718334Speter i = constrain_asm_operands (n_operands, operands, constraints, 86818334Speter operand_matches, operand_class); 86918334Speter if (i < 0) 87018334Speter malformed_asm = 1; 87118334Speter 87218334Speter /* Strip SUBREGs here to make the following code simpler. */ 87318334Speter for (i = 0; i < n_operands; i++) 87418334Speter if (GET_CODE (operands[i]) == SUBREG 87518334Speter && GET_CODE (SUBREG_REG (operands[i])) == REG) 87618334Speter operands[i] = SUBREG_REG (operands[i]); 87718334Speter 87818334Speter /* Set up CLOBBER_REG. */ 87918334Speter 88018334Speter n_clobbers = 0; 88118334Speter 88218334Speter if (GET_CODE (body) == PARALLEL) 88318334Speter { 88418334Speter clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *)); 88518334Speter 88618334Speter for (i = 0; i < XVECLEN (body, 0); i++) 88718334Speter if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) 88818334Speter { 88918334Speter rtx clobber = XVECEXP (body, 0, i); 89018334Speter rtx reg = XEXP (clobber, 0); 89118334Speter 89218334Speter if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG) 89318334Speter reg = SUBREG_REG (reg); 89418334Speter 89518334Speter if (STACK_REG_P (reg)) 89618334Speter { 89718334Speter clobber_reg[n_clobbers] = reg; 89818334Speter n_clobbers++; 89918334Speter } 90018334Speter } 90118334Speter } 90218334Speter 90318334Speter /* Enforce rule #4: Output operands must specifically indicate which 90418334Speter reg an output appears in after an asm. "=f" is not allowed: the 90518334Speter operand constraints must select a class with a single reg. 90618334Speter 90718334Speter Also enforce rule #5: Output operands must start at the top of 90818334Speter the reg-stack: output operands may not "skip" a reg. */ 90918334Speter 91018334Speter bzero ((char *) reg_used_as_output, sizeof (reg_used_as_output)); 91118334Speter for (i = 0; i < n_outputs; i++) 91218334Speter if (STACK_REG_P (operands[i])) 91318334Speter if (reg_class_size[(int) operand_class[i]] != 1) 91418334Speter { 91518334Speter error_for_asm 91618334Speter (insn, "Output constraint %d must specify a single register", i); 91718334Speter malformed_asm = 1; 91818334Speter } 91918334Speter else 92018334Speter reg_used_as_output[REGNO (operands[i])] = 1; 92118334Speter 92218334Speter 92318334Speter /* Search for first non-popped reg. */ 92418334Speter for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++) 92518334Speter if (! reg_used_as_output[i]) 92618334Speter break; 92718334Speter 92818334Speter /* If there are any other popped regs, that's an error. */ 92918334Speter for (; i < LAST_STACK_REG + 1; i++) 93018334Speter if (reg_used_as_output[i]) 93118334Speter break; 93218334Speter 93318334Speter if (i != LAST_STACK_REG + 1) 93418334Speter { 93518334Speter error_for_asm (insn, "Output regs must be grouped at top of stack"); 93618334Speter malformed_asm = 1; 93718334Speter } 93818334Speter 93918334Speter /* Enforce rule #2: All implicitly popped input regs must be closer 94018334Speter to the top of the reg-stack than any input that is not implicitly 94118334Speter popped. */ 94218334Speter 94318334Speter bzero ((char *) implicitly_dies, sizeof (implicitly_dies)); 94418334Speter for (i = first_input; i < first_input + n_inputs; i++) 94518334Speter if (STACK_REG_P (operands[i])) 94618334Speter { 94718334Speter /* An input reg is implicitly popped if it is tied to an 94818334Speter output, or if there is a CLOBBER for it. */ 94918334Speter int j; 95018334Speter 95118334Speter for (j = 0; j < n_clobbers; j++) 95218334Speter if (operands_match_p (clobber_reg[j], operands[i])) 95318334Speter break; 95418334Speter 95518334Speter if (j < n_clobbers || operand_matches[i] >= 0) 95618334Speter implicitly_dies[REGNO (operands[i])] = 1; 95718334Speter } 95818334Speter 95918334Speter /* Search for first non-popped reg. */ 96018334Speter for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++) 96118334Speter if (! implicitly_dies[i]) 96218334Speter break; 96318334Speter 96418334Speter /* If there are any other popped regs, that's an error. */ 96518334Speter for (; i < LAST_STACK_REG + 1; i++) 96618334Speter if (implicitly_dies[i]) 96718334Speter break; 96818334Speter 96918334Speter if (i != LAST_STACK_REG + 1) 97018334Speter { 97118334Speter error_for_asm (insn, 97218334Speter "Implicitly popped regs must be grouped at top of stack"); 97318334Speter malformed_asm = 1; 97418334Speter } 97518334Speter 97618334Speter /* Enfore rule #3: If any input operand uses the "f" constraint, all 97718334Speter output constraints must use the "&" earlyclobber. 97818334Speter 97918334Speter ??? Detect this more deterministically by having constraint_asm_operands 98018334Speter record any earlyclobber. */ 98118334Speter 98218334Speter for (i = first_input; i < first_input + n_inputs; i++) 98318334Speter if (operand_matches[i] == -1) 98418334Speter { 98518334Speter int j; 98618334Speter 98718334Speter for (j = 0; j < n_outputs; j++) 98818334Speter if (operands_match_p (operands[j], operands[i])) 98918334Speter { 99018334Speter error_for_asm (insn, 99118334Speter "Output operand %d must use `&' constraint", j); 99218334Speter malformed_asm = 1; 99318334Speter } 99418334Speter } 99518334Speter 99618334Speter if (malformed_asm) 99718334Speter { 99818334Speter /* Avoid further trouble with this insn. */ 99918334Speter PATTERN (insn) = gen_rtx (USE, VOIDmode, const0_rtx); 100018334Speter PUT_MODE (insn, VOIDmode); 100118334Speter return; 100218334Speter } 100318334Speter 100418334Speter /* Process all outputs */ 100518334Speter for (i = 0; i < n_outputs; i++) 100618334Speter { 100718334Speter rtx op = operands[i]; 100818334Speter 100918334Speter if (! STACK_REG_P (op)) 101018334Speter if (stack_regs_mentioned_p (op)) 101118334Speter abort (); 101218334Speter else 101318334Speter continue; 101418334Speter 101518334Speter /* Each destination is dead before this insn. If the 101618334Speter destination is not used after this insn, record this with 101718334Speter REG_UNUSED. */ 101818334Speter 101918334Speter if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (op))) 102018334Speter REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, op, 102118334Speter REG_NOTES (insn)); 102218334Speter 102318334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (op)); 102418334Speter } 102518334Speter 102618334Speter /* Process all inputs */ 102718334Speter for (i = first_input; i < first_input + n_inputs; i++) 102818334Speter { 102918334Speter if (! STACK_REG_P (operands[i])) 103018334Speter if (stack_regs_mentioned_p (operands[i])) 103118334Speter abort (); 103218334Speter else 103318334Speter continue; 103418334Speter 103518334Speter /* If an input is dead after the insn, record a death note. 103618334Speter But don't record a death note if there is already a death note, 103718334Speter or if the input is also an output. */ 103818334Speter 103918334Speter if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i])) 104018334Speter && operand_matches[i] == -1 104118334Speter && find_regno_note (insn, REG_DEAD, REGNO (operands[i])) == NULL_RTX) 104218334Speter REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, operands[i], 104318334Speter REG_NOTES (insn)); 104418334Speter 104518334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i])); 104618334Speter } 104718334Speter} 104818334Speter 104918334Speter/* Scan PAT, which is part of INSN, and record registers appearing in 105018334Speter a SET_DEST in DEST, and other registers in SRC. 105118334Speter 105218334Speter This function does not know about SET_DESTs that are both input and 105318334Speter output (such as ZERO_EXTRACT) - this cannot happen on a 387. */ 105418334Speter 105518334Speterstatic void 105618334Speterrecord_reg_life_pat (pat, src, dest, douse) 105718334Speter rtx pat; 105818334Speter HARD_REG_SET *src, *dest; 105918334Speter int douse; 106018334Speter{ 106118334Speter register char *fmt; 106218334Speter register int i; 106318334Speter 106418334Speter if (STACK_REG_P (pat) 106518334Speter || GET_CODE (pat) == SUBREG && STACK_REG_P (SUBREG_REG (pat))) 106618334Speter { 106718334Speter if (src) 106818334Speter mark_regs_pat (pat, src); 106918334Speter 107018334Speter if (dest) 107118334Speter mark_regs_pat (pat, dest); 107218334Speter 107318334Speter return; 107418334Speter } 107518334Speter 107618334Speter if (GET_CODE (pat) == SET) 107718334Speter { 107818334Speter record_reg_life_pat (XEXP (pat, 0), NULL_PTR, dest, 0); 107918334Speter record_reg_life_pat (XEXP (pat, 1), src, NULL_PTR, 0); 108018334Speter return; 108118334Speter } 108218334Speter 108318334Speter /* We don't need to consider either of these cases. */ 108418334Speter if (GET_CODE (pat) == USE && !douse || GET_CODE (pat) == CLOBBER) 108518334Speter return; 108618334Speter 108718334Speter fmt = GET_RTX_FORMAT (GET_CODE (pat)); 108818334Speter for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) 108918334Speter { 109018334Speter if (fmt[i] == 'E') 109118334Speter { 109218334Speter register int j; 109318334Speter 109418334Speter for (j = XVECLEN (pat, i) - 1; j >= 0; j--) 109518334Speter record_reg_life_pat (XVECEXP (pat, i, j), src, dest, 0); 109618334Speter } 109718334Speter else if (fmt[i] == 'e') 109818334Speter record_reg_life_pat (XEXP (pat, i), src, dest, 0); 109918334Speter } 110018334Speter} 110118334Speter 110218334Speter/* Calculate the number of inputs and outputs in BODY, an 110318334Speter asm_operands. N_OPERANDS is the total number of operands, and 110418334Speter N_INPUTS and N_OUTPUTS are pointers to ints into which the results are 110518334Speter placed. */ 110618334Speter 110718334Speterstatic void 110818334Speterget_asm_operand_lengths (body, n_operands, n_inputs, n_outputs) 110918334Speter rtx body; 111018334Speter int n_operands; 111118334Speter int *n_inputs, *n_outputs; 111218334Speter{ 111318334Speter if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) 111418334Speter *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)); 111518334Speter 111618334Speter else if (GET_CODE (body) == ASM_OPERANDS) 111718334Speter *n_inputs = ASM_OPERANDS_INPUT_LENGTH (body); 111818334Speter 111918334Speter else if (GET_CODE (body) == PARALLEL 112018334Speter && GET_CODE (XVECEXP (body, 0, 0)) == SET) 112118334Speter *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0))); 112218334Speter 112318334Speter else if (GET_CODE (body) == PARALLEL 112418334Speter && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) 112518334Speter *n_inputs = ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0)); 112618334Speter else 112718334Speter abort (); 112818334Speter 112918334Speter *n_outputs = n_operands - *n_inputs; 113018334Speter} 113118334Speter 113218334Speter/* Scan INSN, which is in BLOCK, and record the life & death of stack 113318334Speter registers in REGSTACK. This function is called to process insns from 113418334Speter the last insn in a block to the first. The actual scanning is done in 113518334Speter record_reg_life_pat. 113618334Speter 113718334Speter If a register is live after a CALL_INSN, but is not a value return 113818334Speter register for that CALL_INSN, then code is emitted to initialize that 113918334Speter register. The block_end[] data is kept accurate. 114018334Speter 114118334Speter Existing death and unset notes for stack registers are deleted 114218334Speter before processing the insn. */ 114318334Speter 114418334Speterstatic void 114518334Speterrecord_reg_life (insn, block, regstack) 114618334Speter rtx insn; 114718334Speter int block; 114818334Speter stack regstack; 114918334Speter{ 115018334Speter rtx note, *note_link; 115118334Speter int n_operands; 115218334Speter 115318334Speter if ((GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN) 115418334Speter || INSN_DELETED_P (insn)) 115518334Speter return; 115618334Speter 115718334Speter /* Strip death notes for stack regs from this insn */ 115818334Speter 115918334Speter note_link = ®_NOTES(insn); 116018334Speter for (note = *note_link; note; note = XEXP (note, 1)) 116118334Speter if (STACK_REG_P (XEXP (note, 0)) 116218334Speter && (REG_NOTE_KIND (note) == REG_DEAD 116318334Speter || REG_NOTE_KIND (note) == REG_UNUSED)) 116418334Speter *note_link = XEXP (note, 1); 116518334Speter else 116618334Speter note_link = &XEXP (note, 1); 116718334Speter 116818334Speter /* Process all patterns in the insn. */ 116918334Speter 117018334Speter n_operands = asm_noperands (PATTERN (insn)); 117118334Speter if (n_operands >= 0) 117218334Speter { 117318334Speter /* This insn is an `asm' with operands. Decode the operands, 117418334Speter decide how many are inputs, and record the life information. */ 117518334Speter 117618334Speter rtx operands[MAX_RECOG_OPERANDS]; 117718334Speter rtx body = PATTERN (insn); 117818334Speter int n_inputs, n_outputs; 117918334Speter char **constraints = (char **) alloca (n_operands * sizeof (char *)); 118018334Speter 118118334Speter decode_asm_operands (body, operands, NULL_PTR, constraints, NULL_PTR); 118218334Speter get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs); 118318334Speter record_asm_reg_life (insn, regstack, operands, constraints, 118418334Speter n_inputs, n_outputs); 118518334Speter return; 118618334Speter } 118718334Speter 118818334Speter { 118918334Speter HARD_REG_SET src, dest; 119018334Speter int regno; 119118334Speter 119218334Speter CLEAR_HARD_REG_SET (src); 119318334Speter CLEAR_HARD_REG_SET (dest); 119418334Speter 119518334Speter if (GET_CODE (insn) == CALL_INSN) 119618334Speter for (note = CALL_INSN_FUNCTION_USAGE (insn); 119718334Speter note; 119818334Speter note = XEXP (note, 1)) 119918334Speter if (GET_CODE (XEXP (note, 0)) == USE) 120018334Speter record_reg_life_pat (SET_DEST (XEXP (note, 0)), &src, NULL_PTR, 0); 120118334Speter 120218334Speter record_reg_life_pat (PATTERN (insn), &src, &dest, 0); 120318334Speter for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++) 120418334Speter if (! TEST_HARD_REG_BIT (regstack->reg_set, regno)) 120518334Speter { 120618334Speter if (TEST_HARD_REG_BIT (src, regno) 120718334Speter && ! TEST_HARD_REG_BIT (dest, regno)) 120818334Speter REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, 120918334Speter FP_MODE_REG (regno, DFmode), 121018334Speter REG_NOTES (insn)); 121118334Speter else if (TEST_HARD_REG_BIT (dest, regno)) 121218334Speter REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, 121318334Speter FP_MODE_REG (regno, DFmode), 121418334Speter REG_NOTES (insn)); 121518334Speter } 121618334Speter 121718334Speter if (GET_CODE (insn) == CALL_INSN) 121818334Speter { 121918334Speter int reg; 122018334Speter 122118334Speter /* There might be a reg that is live after a function call. 122218334Speter Initialize it to zero so that the program does not crash. See 122318334Speter comment towards the end of stack_reg_life_analysis(). */ 122418334Speter 122518334Speter for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++) 122618334Speter if (! TEST_HARD_REG_BIT (dest, reg) 122718334Speter && TEST_HARD_REG_BIT (regstack->reg_set, reg)) 122818334Speter { 122918334Speter rtx init, pat; 123018334Speter 123118334Speter /* The insn will use virtual register numbers, and so 123218334Speter convert_regs is expected to process these. But BLOCK_NUM 123318334Speter cannot be used on these insns, because they do not appear in 123418334Speter block_number[]. */ 123518334Speter 123618334Speter pat = gen_rtx (SET, VOIDmode, FP_MODE_REG (reg, DFmode), 123718334Speter CONST0_RTX (DFmode)); 123818334Speter init = emit_insn_after (pat, insn); 123918334Speter PUT_MODE (init, QImode); 124018334Speter 124118334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, reg); 124218334Speter 124318334Speter /* If the CALL_INSN was the end of a block, move the 124418334Speter block_end to point to the new insn. */ 124518334Speter 124618334Speter if (block_end[block] == insn) 124718334Speter block_end[block] = init; 124818334Speter } 124918334Speter 125018334Speter /* Some regs do not survive a CALL */ 125118334Speter AND_COMPL_HARD_REG_SET (regstack->reg_set, call_used_reg_set); 125218334Speter } 125318334Speter 125418334Speter AND_COMPL_HARD_REG_SET (regstack->reg_set, dest); 125518334Speter IOR_HARD_REG_SET (regstack->reg_set, src); 125618334Speter } 125718334Speter} 125818334Speter 125918334Speter/* Find all basic blocks of the function, which starts with FIRST. 126018334Speter For each JUMP_INSN, build the chain of LABEL_REFS on each CODE_LABEL. */ 126118334Speter 126218334Speterstatic void 126318334Speterfind_blocks (first) 126418334Speter rtx first; 126518334Speter{ 126618334Speter register rtx insn; 126718334Speter register int block; 126818334Speter register RTX_CODE prev_code = BARRIER; 126918334Speter register RTX_CODE code; 127018334Speter rtx label_value_list = 0; 127118334Speter 127218334Speter /* Record where all the blocks start and end. 127318334Speter Record which basic blocks control can drop in to. */ 127418334Speter 127518334Speter block = -1; 127618334Speter for (insn = first; insn; insn = NEXT_INSN (insn)) 127718334Speter { 127818334Speter /* Note that this loop must select the same block boundaries 127918334Speter as code in reg_to_stack, but that these are not the same 128018334Speter as those selected in flow.c. */ 128118334Speter 128218334Speter code = GET_CODE (insn); 128318334Speter 128418334Speter if (code == CODE_LABEL 128518334Speter || (prev_code != INSN 128618334Speter && prev_code != CALL_INSN 128718334Speter && prev_code != CODE_LABEL 128818334Speter && GET_RTX_CLASS (code) == 'i')) 128918334Speter { 129018334Speter block_begin[++block] = insn; 129118334Speter block_end[block] = insn; 129218334Speter block_drops_in[block] = prev_code != BARRIER; 129318334Speter } 129418334Speter else if (GET_RTX_CLASS (code) == 'i') 129518334Speter block_end[block] = insn; 129618334Speter 129718334Speter if (GET_RTX_CLASS (code) == 'i') 129818334Speter { 129918334Speter rtx note; 130018334Speter 130118334Speter /* Make a list of all labels referred to other than by jumps. */ 130218334Speter for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) 130318334Speter if (REG_NOTE_KIND (note) == REG_LABEL) 130418334Speter label_value_list = gen_rtx (EXPR_LIST, VOIDmode, XEXP (note, 0), 130518334Speter label_value_list); 130618334Speter } 130718334Speter 130818334Speter block_number[INSN_UID (insn)] = block; 130918334Speter 131018334Speter if (code != NOTE) 131118334Speter prev_code = code; 131218334Speter } 131318334Speter 131418334Speter if (block + 1 != blocks) 131518334Speter abort (); 131618334Speter 131718334Speter /* generate all label references to the corresponding jump insn */ 131818334Speter for (block = 0; block < blocks; block++) 131918334Speter { 132018334Speter insn = block_end[block]; 132118334Speter 132218334Speter if (GET_CODE (insn) == JUMP_INSN) 132318334Speter { 132418334Speter rtx pat = PATTERN (insn); 132518334Speter int computed_jump = 0; 132618334Speter rtx x; 132718334Speter 132818334Speter if (GET_CODE (pat) == PARALLEL) 132918334Speter { 133018334Speter int len = XVECLEN (pat, 0); 133118334Speter int has_use_labelref = 0; 133218334Speter int i; 133318334Speter 133418334Speter for (i = len - 1; i >= 0; i--) 133518334Speter if (GET_CODE (XVECEXP (pat, 0, i)) == USE 133618334Speter && GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == LABEL_REF) 133718334Speter has_use_labelref = 1; 133818334Speter 133918334Speter if (! has_use_labelref) 134018334Speter for (i = len - 1; i >= 0; i--) 134118334Speter if (GET_CODE (XVECEXP (pat, 0, i)) == SET 134218334Speter && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx 134318334Speter && uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i)))) 134418334Speter computed_jump = 1; 134518334Speter } 134618334Speter else if (GET_CODE (pat) == SET 134718334Speter && SET_DEST (pat) == pc_rtx 134818334Speter && uses_reg_or_mem (SET_SRC (pat))) 134918334Speter computed_jump = 1; 135018334Speter 135118334Speter if (computed_jump) 135218334Speter { 135318334Speter for (x = label_value_list; x; x = XEXP (x, 1)) 135418334Speter record_label_references (insn, 135518334Speter gen_rtx (LABEL_REF, VOIDmode, 135618334Speter XEXP (x, 0))); 135718334Speter 135818334Speter for (x = forced_labels; x; x = XEXP (x, 1)) 135918334Speter record_label_references (insn, 136018334Speter gen_rtx (LABEL_REF, VOIDmode, 136118334Speter XEXP (x, 0))); 136218334Speter } 136318334Speter 136418334Speter record_label_references (insn, pat); 136518334Speter } 136618334Speter } 136718334Speter} 136818334Speter 136918334Speter/* Return 1 if X contain a REG or MEM that is not in the constant pool. */ 137018334Speter 137118334Speterstatic int 137218334Speteruses_reg_or_mem (x) 137318334Speter rtx x; 137418334Speter{ 137518334Speter enum rtx_code code = GET_CODE (x); 137618334Speter int i, j; 137718334Speter char *fmt; 137818334Speter 137918334Speter if (code == REG 138018334Speter || (code == MEM 138118334Speter && ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF 138218334Speter && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))))) 138318334Speter return 1; 138418334Speter 138518334Speter fmt = GET_RTX_FORMAT (code); 138618334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 138718334Speter { 138818334Speter if (fmt[i] == 'e' 138918334Speter && uses_reg_or_mem (XEXP (x, i))) 139018334Speter return 1; 139118334Speter 139218334Speter if (fmt[i] == 'E') 139318334Speter for (j = 0; j < XVECLEN (x, i); j++) 139418334Speter if (uses_reg_or_mem (XVECEXP (x, i, j))) 139518334Speter return 1; 139618334Speter } 139718334Speter 139818334Speter return 0; 139918334Speter} 140018334Speter 140118334Speter/* If current function returns its result in an fp stack register, 140218334Speter return the REG. Otherwise, return 0. */ 140318334Speter 140418334Speterstatic rtx 140518334Speterstack_result (decl) 140618334Speter tree decl; 140718334Speter{ 140818334Speter rtx result = DECL_RTL (DECL_RESULT (decl)); 140918334Speter 141018334Speter if (result != 0 141118334Speter && ! (GET_CODE (result) == REG 141218334Speter && REGNO (result) < FIRST_PSEUDO_REGISTER)) 141318334Speter { 141418334Speter#ifdef FUNCTION_OUTGOING_VALUE 141518334Speter result 141618334Speter = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl); 141718334Speter#else 141818334Speter result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl); 141918334Speter#endif 142018334Speter } 142118334Speter 142218334Speter return result != 0 && STACK_REG_P (result) ? result : 0; 142318334Speter} 142418334Speter 142518334Speter/* Determine the which registers are live at the start of each basic 142618334Speter block of the function whose first insn is FIRST. 142718334Speter 142818334Speter First, if the function returns a real_type, mark the function 142918334Speter return type as live at each return point, as the RTL may not give any 143018334Speter hint that the register is live. 143118334Speter 143218334Speter Then, start with the last block and work back to the first block. 143318334Speter Similarly, work backwards within each block, insn by insn, recording 143418334Speter which regs are dead and which are used (and therefore live) in the 143518334Speter hard reg set of block_stack_in[]. 143618334Speter 143718334Speter After processing each basic block, if there is a label at the start 143818334Speter of the block, propagate the live registers to all jumps to this block. 143918334Speter 144018334Speter As a special case, if there are regs live in this block, that are 144118334Speter not live in a block containing a jump to this label, and the block 144218334Speter containing the jump has already been processed, we must propagate this 144318334Speter block's entry register life back to the block containing the jump, and 144418334Speter restart life analysis from there. 144518334Speter 144618334Speter In the worst case, this function may traverse the insns 144718334Speter REG_STACK_SIZE times. This is necessary, since a jump towards the end 144818334Speter of the insns may not know that a reg is live at a target that is early 144918334Speter in the insns. So we back up and start over with the new reg live. 145018334Speter 145118334Speter If there are registers that are live at the start of the function, 145218334Speter insns are emitted to initialize these registers. Something similar is 145318334Speter done after CALL_INSNs in record_reg_life. */ 145418334Speter 145518334Speterstatic void 145618334Speterstack_reg_life_analysis (first, stackentry) 145718334Speter rtx first; 145818334Speter HARD_REG_SET *stackentry; 145918334Speter{ 146018334Speter int reg, block; 146118334Speter struct stack_def regstack; 146218334Speter 146318334Speter { 146418334Speter rtx retvalue; 146518334Speter 146618334Speter if (retvalue = stack_result (current_function_decl)) 146718334Speter { 146818334Speter /* Find all RETURN insns and mark them. */ 146918334Speter 147018334Speter for (block = blocks - 1; --block >= 0;) 147118334Speter if (GET_CODE (block_end[block]) == JUMP_INSN 147218334Speter && GET_CODE (PATTERN (block_end[block])) == RETURN) 147318334Speter mark_regs_pat (retvalue, block_out_reg_set+block); 147418334Speter 147518334Speter /* Mark off the end of last block if we "fall off" the end of the 147618334Speter function into the epilogue. */ 147718334Speter 147818334Speter if (GET_CODE (block_end[blocks-1]) != JUMP_INSN 147918334Speter || GET_CODE (PATTERN (block_end[blocks-1])) == RETURN) 148018334Speter mark_regs_pat (retvalue, block_out_reg_set+blocks-1); 148118334Speter } 148218334Speter } 148318334Speter 148418334Speter /* now scan all blocks backward for stack register use */ 148518334Speter 148618334Speter block = blocks - 1; 148718334Speter while (block >= 0) 148818334Speter { 148918334Speter register rtx insn, prev; 149018334Speter 149118334Speter /* current register status at last instruction */ 149218334Speter 149318334Speter COPY_HARD_REG_SET (regstack.reg_set, block_out_reg_set[block]); 149418334Speter 149518334Speter prev = block_end[block]; 149618334Speter do 149718334Speter { 149818334Speter insn = prev; 149918334Speter prev = PREV_INSN (insn); 150018334Speter 150118334Speter /* If the insn is a CALL_INSN, we need to ensure that 150218334Speter everything dies. But otherwise don't process unless there 150318334Speter are some stack regs present. */ 150418334Speter 150518334Speter if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN) 150618334Speter record_reg_life (insn, block, ®stack); 150718334Speter 150818334Speter } while (insn != block_begin[block]); 150918334Speter 151018334Speter /* Set the state at the start of the block. Mark that no 151118334Speter register mapping information known yet. */ 151218334Speter 151318334Speter COPY_HARD_REG_SET (block_stack_in[block].reg_set, regstack.reg_set); 151418334Speter block_stack_in[block].top = -2; 151518334Speter 151618334Speter /* If there is a label, propagate our register life to all jumps 151718334Speter to this label. */ 151818334Speter 151918334Speter if (GET_CODE (insn) == CODE_LABEL) 152018334Speter { 152118334Speter register rtx label; 152218334Speter int must_restart = 0; 152318334Speter 152418334Speter for (label = LABEL_REFS (insn); label != insn; 152518334Speter label = LABEL_NEXTREF (label)) 152618334Speter { 152718334Speter int jump_block = BLOCK_NUM (CONTAINING_INSN (label)); 152818334Speter 152918334Speter if (jump_block < block) 153018334Speter IOR_HARD_REG_SET (block_out_reg_set[jump_block], 153118334Speter block_stack_in[block].reg_set); 153218334Speter else 153318334Speter { 153418334Speter /* The block containing the jump has already been 153518334Speter processed. If there are registers that were not known 153618334Speter to be live then, but are live now, we must back up 153718334Speter and restart life analysis from that point with the new 153818334Speter life information. */ 153918334Speter 154018334Speter GO_IF_HARD_REG_SUBSET (block_stack_in[block].reg_set, 154118334Speter block_out_reg_set[jump_block], 154218334Speter win); 154318334Speter 154418334Speter IOR_HARD_REG_SET (block_out_reg_set[jump_block], 154518334Speter block_stack_in[block].reg_set); 154618334Speter 154718334Speter block = jump_block; 154818334Speter must_restart = 1; 154918334Speter 155018334Speter win: 155118334Speter ; 155218334Speter } 155318334Speter } 155418334Speter if (must_restart) 155518334Speter continue; 155618334Speter } 155718334Speter 155818334Speter if (block_drops_in[block]) 155918334Speter IOR_HARD_REG_SET (block_out_reg_set[block-1], 156018334Speter block_stack_in[block].reg_set); 156118334Speter 156218334Speter block -= 1; 156318334Speter } 156418334Speter 156518334Speter /* If any reg is live at the start of the first block of a 156618334Speter function, then we must guarantee that the reg holds some value by 156718334Speter generating our own "load" of that register. Otherwise a 387 would 156818334Speter fault trying to access an empty register. */ 156918334Speter 157018334Speter /* Load zero into each live register. The fact that a register 157118334Speter appears live at the function start necessarily implies an error 157218334Speter in the user program: it means that (unless the offending code is *never* 157318334Speter executed) this program is using uninitialised floating point 157418334Speter variables. In order to keep broken code like this happy, we initialise 157518334Speter those variables with zero. 157618334Speter 157718334Speter Note that we are inserting virtual register references here: 157818334Speter these insns must be processed by convert_regs later. Also, these 157918334Speter insns will not be in block_number, so BLOCK_NUM() will fail for them. */ 158018334Speter 158118334Speter for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--) 158218334Speter if (TEST_HARD_REG_BIT (block_stack_in[0].reg_set, reg) 158318334Speter && ! TEST_HARD_REG_BIT (*stackentry, reg)) 158418334Speter { 158518334Speter rtx init_rtx; 158618334Speter 158718334Speter init_rtx = gen_rtx (SET, VOIDmode, FP_MODE_REG(reg, DFmode), 158818334Speter CONST0_RTX (DFmode)); 158918334Speter block_begin[0] = emit_insn_after (init_rtx, first); 159018334Speter PUT_MODE (block_begin[0], QImode); 159118334Speter 159218334Speter CLEAR_HARD_REG_BIT (block_stack_in[0].reg_set, reg); 159318334Speter } 159418334Speter} 159518334Speter 159618334Speter/***************************************************************************** 159718334Speter This section deals with stack register substitution, and forms the second 159818334Speter pass over the RTL. 159918334Speter *****************************************************************************/ 160018334Speter 160118334Speter/* Replace REG, which is a pointer to a stack reg RTX, with an RTX for 160218334Speter the desired hard REGNO. */ 160318334Speter 160418334Speterstatic void 160518334Speterreplace_reg (reg, regno) 160618334Speter rtx *reg; 160718334Speter int regno; 160818334Speter{ 160918334Speter if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG 161018334Speter || ! STACK_REG_P (*reg)) 161118334Speter abort (); 161218334Speter 161318334Speter switch (GET_MODE_CLASS (GET_MODE (*reg))) 161418334Speter { 161518334Speter default: abort (); 161618334Speter case MODE_FLOAT: 161718334Speter case MODE_COMPLEX_FLOAT:; 161818334Speter } 161918334Speter 162018334Speter *reg = FP_MODE_REG (regno, GET_MODE (*reg)); 162118334Speter} 162218334Speter 162318334Speter/* Remove a note of type NOTE, which must be found, for register 162418334Speter number REGNO from INSN. Remove only one such note. */ 162518334Speter 162618334Speterstatic void 162718334Speterremove_regno_note (insn, note, regno) 162818334Speter rtx insn; 162918334Speter enum reg_note note; 163018334Speter int regno; 163118334Speter{ 163218334Speter register rtx *note_link, this; 163318334Speter 163418334Speter note_link = ®_NOTES(insn); 163518334Speter for (this = *note_link; this; this = XEXP (this, 1)) 163618334Speter if (REG_NOTE_KIND (this) == note 163718334Speter && REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno) 163818334Speter { 163918334Speter *note_link = XEXP (this, 1); 164018334Speter return; 164118334Speter } 164218334Speter else 164318334Speter note_link = &XEXP (this, 1); 164418334Speter 164518334Speter abort (); 164618334Speter} 164718334Speter 164818334Speter/* Find the hard register number of virtual register REG in REGSTACK. 164918334Speter The hard register number is relative to the top of the stack. -1 is 165018334Speter returned if the register is not found. */ 165118334Speter 165218334Speterstatic int 165318334Speterget_hard_regnum (regstack, reg) 165418334Speter stack regstack; 165518334Speter rtx reg; 165618334Speter{ 165718334Speter int i; 165818334Speter 165918334Speter if (! STACK_REG_P (reg)) 166018334Speter abort (); 166118334Speter 166218334Speter for (i = regstack->top; i >= 0; i--) 166318334Speter if (regstack->reg[i] == REGNO (reg)) 166418334Speter break; 166518334Speter 166618334Speter return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1; 166718334Speter} 166818334Speter 166918334Speter/* Delete INSN from the RTL. Mark the insn, but don't remove it from 167018334Speter the chain of insns. Doing so could confuse block_begin and block_end 167118334Speter if this were the only insn in the block. */ 167218334Speter 167318334Speterstatic void 167418334Speterdelete_insn_for_stacker (insn) 167518334Speter rtx insn; 167618334Speter{ 167718334Speter PUT_CODE (insn, NOTE); 167818334Speter NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 167918334Speter NOTE_SOURCE_FILE (insn) = 0; 168018334Speter} 168118334Speter 168218334Speter/* Emit an insn to pop virtual register REG before or after INSN. 168318334Speter REGSTACK is the stack state after INSN and is updated to reflect this 168418334Speter pop. WHEN is either emit_insn_before or emit_insn_after. A pop insn 168518334Speter is represented as a SET whose destination is the register to be popped 168618334Speter and source is the top of stack. A death note for the top of stack 168718334Speter cases the movdf pattern to pop. */ 168818334Speter 168918334Speterstatic rtx 169018334Speteremit_pop_insn (insn, regstack, reg, when) 169118334Speter rtx insn; 169218334Speter stack regstack; 169318334Speter rtx reg; 169418334Speter rtx (*when)(); 169518334Speter{ 169618334Speter rtx pop_insn, pop_rtx; 169718334Speter int hard_regno; 169818334Speter 169918334Speter hard_regno = get_hard_regnum (regstack, reg); 170018334Speter 170118334Speter if (hard_regno < FIRST_STACK_REG) 170218334Speter abort (); 170318334Speter 170418334Speter pop_rtx = gen_rtx (SET, VOIDmode, FP_MODE_REG (hard_regno, DFmode), 170518334Speter FP_MODE_REG (FIRST_STACK_REG, DFmode)); 170618334Speter 170718334Speter pop_insn = (*when) (pop_rtx, insn); 170818334Speter /* ??? This used to be VOIDmode, but that seems wrong. */ 170918334Speter PUT_MODE (pop_insn, QImode); 171018334Speter 171118334Speter REG_NOTES (pop_insn) = gen_rtx (EXPR_LIST, REG_DEAD, 171218334Speter FP_MODE_REG (FIRST_STACK_REG, DFmode), 171318334Speter REG_NOTES (pop_insn)); 171418334Speter 171518334Speter regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)] 171618334Speter = regstack->reg[regstack->top]; 171718334Speter regstack->top -= 1; 171818334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg)); 171918334Speter 172018334Speter return pop_insn; 172118334Speter} 172218334Speter 172318334Speter/* Emit an insn before or after INSN to swap virtual register REG with the 172418334Speter top of stack. WHEN should be `emit_insn_before' or `emit_insn_before' 172518334Speter REGSTACK is the stack state before the swap, and is updated to reflect 172618334Speter the swap. A swap insn is represented as a PARALLEL of two patterns: 172718334Speter each pattern moves one reg to the other. 172818334Speter 172918334Speter If REG is already at the top of the stack, no insn is emitted. */ 173018334Speter 173118334Speterstatic void 173218334Speteremit_swap_insn (insn, regstack, reg) 173318334Speter rtx insn; 173418334Speter stack regstack; 173518334Speter rtx reg; 173618334Speter{ 173718334Speter int hard_regno; 173818334Speter rtx gen_swapdf(); 173918334Speter rtx swap_rtx, swap_insn; 174018334Speter int tmp, other_reg; /* swap regno temps */ 174118334Speter rtx i1; /* the stack-reg insn prior to INSN */ 174218334Speter rtx i1set = NULL_RTX; /* the SET rtx within I1 */ 174318334Speter 174418334Speter hard_regno = get_hard_regnum (regstack, reg); 174518334Speter 174618334Speter if (hard_regno < FIRST_STACK_REG) 174718334Speter abort (); 174818334Speter if (hard_regno == FIRST_STACK_REG) 174918334Speter return; 175018334Speter 175118334Speter other_reg = regstack->top - (hard_regno - FIRST_STACK_REG); 175218334Speter 175318334Speter tmp = regstack->reg[other_reg]; 175418334Speter regstack->reg[other_reg] = regstack->reg[regstack->top]; 175518334Speter regstack->reg[regstack->top] = tmp; 175618334Speter 175718334Speter /* Find the previous insn involving stack regs, but don't go past 175818334Speter any labels, calls or jumps. */ 175918334Speter i1 = prev_nonnote_insn (insn); 176018334Speter while (i1 && GET_CODE (i1) == INSN && GET_MODE (i1) != QImode) 176118334Speter i1 = prev_nonnote_insn (i1); 176218334Speter 176318334Speter if (i1) 176418334Speter i1set = single_set (i1); 176518334Speter 176618334Speter if (i1set) 176718334Speter { 176818334Speter rtx i2; /* the stack-reg insn prior to I1 */ 176918334Speter rtx i1src = *get_true_reg (&SET_SRC (i1set)); 177018334Speter rtx i1dest = *get_true_reg (&SET_DEST (i1set)); 177118334Speter 177218334Speter /* If the previous register stack push was from the reg we are to 177318334Speter swap with, omit the swap. */ 177418334Speter 177518334Speter if (GET_CODE (i1dest) == REG && REGNO (i1dest) == FIRST_STACK_REG 177618334Speter && GET_CODE (i1src) == REG && REGNO (i1src) == hard_regno - 1 177718334Speter && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX) 177818334Speter return; 177918334Speter 178018334Speter /* If the previous insn wrote to the reg we are to swap with, 178118334Speter omit the swap. */ 178218334Speter 178318334Speter if (GET_CODE (i1dest) == REG && REGNO (i1dest) == hard_regno 178418334Speter && GET_CODE (i1src) == REG && REGNO (i1src) == FIRST_STACK_REG 178518334Speter && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX) 178618334Speter return; 178718334Speter } 178818334Speter 178918334Speter if (GET_RTX_CLASS (GET_CODE (i1)) == 'i' && sets_cc0_p (PATTERN (i1))) 179018334Speter { 179118334Speter i1 = next_nonnote_insn (i1); 179218334Speter if (i1 == insn) 179318334Speter abort (); 179418334Speter } 179518334Speter 179618334Speter swap_rtx = gen_swapdf (FP_MODE_REG (hard_regno, DFmode), 179718334Speter FP_MODE_REG (FIRST_STACK_REG, DFmode)); 179818334Speter swap_insn = emit_insn_after (swap_rtx, i1); 179918334Speter /* ??? This used to be VOIDmode, but that seems wrong. */ 180018334Speter PUT_MODE (swap_insn, QImode); 180118334Speter} 180218334Speter 180318334Speter/* Handle a move to or from a stack register in PAT, which is in INSN. 180418334Speter REGSTACK is the current stack. */ 180518334Speter 180618334Speterstatic void 180718334Spetermove_for_stack_reg (insn, regstack, pat) 180818334Speter rtx insn; 180918334Speter stack regstack; 181018334Speter rtx pat; 181118334Speter{ 181218334Speter rtx *psrc = get_true_reg (&SET_SRC (pat)); 181318334Speter rtx *pdest = get_true_reg (&SET_DEST (pat)); 181418334Speter rtx src, dest; 181518334Speter rtx note; 181618334Speter 181718334Speter src = *psrc; dest = *pdest; 181818334Speter 181918334Speter if (STACK_REG_P (src) && STACK_REG_P (dest)) 182018334Speter { 182118334Speter /* Write from one stack reg to another. If SRC dies here, then 182218334Speter just change the register mapping and delete the insn. */ 182318334Speter 182418334Speter note = find_regno_note (insn, REG_DEAD, REGNO (src)); 182518334Speter if (note) 182618334Speter { 182718334Speter int i; 182818334Speter 182918334Speter /* If this is a no-op move, there must not be a REG_DEAD note. */ 183018334Speter if (REGNO (src) == REGNO (dest)) 183118334Speter abort (); 183218334Speter 183318334Speter for (i = regstack->top; i >= 0; i--) 183418334Speter if (regstack->reg[i] == REGNO (src)) 183518334Speter break; 183618334Speter 183718334Speter /* The source must be live, and the dest must be dead. */ 183818334Speter if (i < 0 || get_hard_regnum (regstack, dest) >= FIRST_STACK_REG) 183918334Speter abort (); 184018334Speter 184118334Speter /* It is possible that the dest is unused after this insn. 184218334Speter If so, just pop the src. */ 184318334Speter 184418334Speter if (find_regno_note (insn, REG_UNUSED, REGNO (dest))) 184518334Speter { 184618334Speter emit_pop_insn (insn, regstack, src, emit_insn_after); 184718334Speter 184818334Speter delete_insn_for_stacker (insn); 184918334Speter return; 185018334Speter } 185118334Speter 185218334Speter regstack->reg[i] = REGNO (dest); 185318334Speter 185418334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); 185518334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src)); 185618334Speter 185718334Speter delete_insn_for_stacker (insn); 185818334Speter 185918334Speter return; 186018334Speter } 186118334Speter 186218334Speter /* The source reg does not die. */ 186318334Speter 186418334Speter /* If this appears to be a no-op move, delete it, or else it 186518334Speter will confuse the machine description output patterns. But if 186618334Speter it is REG_UNUSED, we must pop the reg now, as per-insn processing 186718334Speter for REG_UNUSED will not work for deleted insns. */ 186818334Speter 186918334Speter if (REGNO (src) == REGNO (dest)) 187018334Speter { 187118334Speter if (find_regno_note (insn, REG_UNUSED, REGNO (dest))) 187218334Speter emit_pop_insn (insn, regstack, dest, emit_insn_after); 187318334Speter 187418334Speter delete_insn_for_stacker (insn); 187518334Speter return; 187618334Speter } 187718334Speter 187818334Speter /* The destination ought to be dead */ 187918334Speter if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG) 188018334Speter abort (); 188118334Speter 188218334Speter replace_reg (psrc, get_hard_regnum (regstack, src)); 188318334Speter 188418334Speter regstack->reg[++regstack->top] = REGNO (dest); 188518334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); 188618334Speter replace_reg (pdest, FIRST_STACK_REG); 188718334Speter } 188818334Speter else if (STACK_REG_P (src)) 188918334Speter { 189018334Speter /* Save from a stack reg to MEM, or possibly integer reg. Since 189118334Speter only top of stack may be saved, emit an exchange first if 189218334Speter needs be. */ 189318334Speter 189418334Speter emit_swap_insn (insn, regstack, src); 189518334Speter 189618334Speter note = find_regno_note (insn, REG_DEAD, REGNO (src)); 189718334Speter if (note) 189818334Speter { 189918334Speter replace_reg (&XEXP (note, 0), FIRST_STACK_REG); 190018334Speter regstack->top--; 190118334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src)); 190218334Speter } 190318334Speter else if (GET_MODE (src) == XFmode && regstack->top != REG_STACK_SIZE) 190418334Speter { 190518334Speter /* A 387 cannot write an XFmode value to a MEM without 190618334Speter clobbering the source reg. The output code can handle 190718334Speter this by reading back the value from the MEM. 190818334Speter But it is more efficient to use a temp register if one is 190918334Speter available. Push the source value here if the register 191018334Speter stack is not full, and then write the value to memory via 191118334Speter a pop. */ 191218334Speter rtx push_rtx, push_insn; 191318334Speter rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, XFmode); 191418334Speter 191518334Speter push_rtx = gen_movxf (top_stack_reg, top_stack_reg); 191618334Speter push_insn = emit_insn_before (push_rtx, insn); 191718334Speter PUT_MODE (push_insn, QImode); 191818334Speter REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, top_stack_reg, 191918334Speter REG_NOTES (insn)); 192018334Speter } 192118334Speter 192218334Speter replace_reg (psrc, FIRST_STACK_REG); 192318334Speter } 192418334Speter else if (STACK_REG_P (dest)) 192518334Speter { 192618334Speter /* Load from MEM, or possibly integer REG or constant, into the 192718334Speter stack regs. The actual target is always the top of the 192818334Speter stack. The stack mapping is changed to reflect that DEST is 192918334Speter now at top of stack. */ 193018334Speter 193118334Speter /* The destination ought to be dead */ 193218334Speter if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG) 193318334Speter abort (); 193418334Speter 193518334Speter if (regstack->top >= REG_STACK_SIZE) 193618334Speter abort (); 193718334Speter 193818334Speter regstack->reg[++regstack->top] = REGNO (dest); 193918334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); 194018334Speter replace_reg (pdest, FIRST_STACK_REG); 194118334Speter } 194218334Speter else 194318334Speter abort (); 194418334Speter} 194518334Speter 194618334Spetervoid 194718334Speterswap_rtx_condition (pat) 194818334Speter rtx pat; 194918334Speter{ 195018334Speter register char *fmt; 195118334Speter register int i; 195218334Speter 195318334Speter if (GET_RTX_CLASS (GET_CODE (pat)) == '<') 195418334Speter { 195518334Speter PUT_CODE (pat, swap_condition (GET_CODE (pat))); 195618334Speter return; 195718334Speter } 195818334Speter 195918334Speter fmt = GET_RTX_FORMAT (GET_CODE (pat)); 196018334Speter for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) 196118334Speter { 196218334Speter if (fmt[i] == 'E') 196318334Speter { 196418334Speter register int j; 196518334Speter 196618334Speter for (j = XVECLEN (pat, i) - 1; j >= 0; j--) 196718334Speter swap_rtx_condition (XVECEXP (pat, i, j)); 196818334Speter } 196918334Speter else if (fmt[i] == 'e') 197018334Speter swap_rtx_condition (XEXP (pat, i)); 197118334Speter } 197218334Speter} 197318334Speter 197418334Speter/* Handle a comparison. Special care needs to be taken to avoid 197518334Speter causing comparisons that a 387 cannot do correctly, such as EQ. 197618334Speter 197718334Speter Also, a pop insn may need to be emitted. The 387 does have an 197818334Speter `fcompp' insn that can pop two regs, but it is sometimes too expensive 197918334Speter to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to 198018334Speter set up. */ 198118334Speter 198218334Speterstatic void 198318334Spetercompare_for_stack_reg (insn, regstack, pat) 198418334Speter rtx insn; 198518334Speter stack regstack; 198618334Speter rtx pat; 198718334Speter{ 198818334Speter rtx *src1, *src2; 198918334Speter rtx src1_note, src2_note; 199018334Speter 199118334Speter src1 = get_true_reg (&XEXP (SET_SRC (pat), 0)); 199218334Speter src2 = get_true_reg (&XEXP (SET_SRC (pat), 1)); 199318334Speter 199418334Speter /* ??? If fxch turns out to be cheaper than fstp, give priority to 199518334Speter registers that die in this insn - move those to stack top first. */ 199618334Speter if (! STACK_REG_P (*src1) 199718334Speter || (STACK_REG_P (*src2) 199818334Speter && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG)) 199918334Speter { 200018334Speter rtx temp, next; 200118334Speter 200218334Speter temp = XEXP (SET_SRC (pat), 0); 200318334Speter XEXP (SET_SRC (pat), 0) = XEXP (SET_SRC (pat), 1); 200418334Speter XEXP (SET_SRC (pat), 1) = temp; 200518334Speter 200618334Speter src1 = get_true_reg (&XEXP (SET_SRC (pat), 0)); 200718334Speter src2 = get_true_reg (&XEXP (SET_SRC (pat), 1)); 200818334Speter 200918334Speter next = next_cc0_user (insn); 201018334Speter if (next == NULL_RTX) 201118334Speter abort (); 201218334Speter 201318334Speter swap_rtx_condition (PATTERN (next)); 201418334Speter INSN_CODE (next) = -1; 201518334Speter INSN_CODE (insn) = -1; 201618334Speter } 201718334Speter 201818334Speter /* We will fix any death note later. */ 201918334Speter 202018334Speter src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); 202118334Speter 202218334Speter if (STACK_REG_P (*src2)) 202318334Speter src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); 202418334Speter else 202518334Speter src2_note = NULL_RTX; 202618334Speter 202718334Speter emit_swap_insn (insn, regstack, *src1); 202818334Speter 202918334Speter replace_reg (src1, FIRST_STACK_REG); 203018334Speter 203118334Speter if (STACK_REG_P (*src2)) 203218334Speter replace_reg (src2, get_hard_regnum (regstack, *src2)); 203318334Speter 203418334Speter if (src1_note) 203518334Speter { 203618334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src1_note, 0))); 203718334Speter replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); 203818334Speter regstack->top--; 203918334Speter } 204018334Speter 204118334Speter /* If the second operand dies, handle that. But if the operands are 204218334Speter the same stack register, don't bother, because only one death is 204318334Speter needed, and it was just handled. */ 204418334Speter 204518334Speter if (src2_note 204618334Speter && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2) 204718334Speter && REGNO (*src1) == REGNO (*src2))) 204818334Speter { 204918334Speter /* As a special case, two regs may die in this insn if src2 is 205018334Speter next to top of stack and the top of stack also dies. Since 205118334Speter we have already popped src1, "next to top of stack" is really 205218334Speter at top (FIRST_STACK_REG) now. */ 205318334Speter 205418334Speter if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG 205518334Speter && src1_note) 205618334Speter { 205718334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src2_note, 0))); 205818334Speter replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1); 205918334Speter regstack->top--; 206018334Speter } 206118334Speter else 206218334Speter { 206318334Speter /* The 386 can only represent death of the first operand in 206418334Speter the case handled above. In all other cases, emit a separate 206518334Speter pop and remove the death note from here. */ 206618334Speter 206718334Speter link_cc0_insns (insn); 206818334Speter 206918334Speter remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0))); 207018334Speter 207118334Speter emit_pop_insn (insn, regstack, XEXP (src2_note, 0), 207218334Speter emit_insn_after); 207318334Speter } 207418334Speter } 207518334Speter} 207618334Speter 207718334Speter/* Substitute new registers in PAT, which is part of INSN. REGSTACK 207818334Speter is the current register layout. */ 207918334Speter 208018334Speterstatic void 208118334Spetersubst_stack_regs_pat (insn, regstack, pat) 208218334Speter rtx insn; 208318334Speter stack regstack; 208418334Speter rtx pat; 208518334Speter{ 208618334Speter rtx *dest, *src; 208718334Speter rtx *src1 = (rtx *) NULL_PTR, *src2; 208818334Speter rtx src1_note, src2_note; 208918334Speter 209018334Speter if (GET_CODE (pat) != SET) 209118334Speter return; 209218334Speter 209318334Speter dest = get_true_reg (&SET_DEST (pat)); 209418334Speter src = get_true_reg (&SET_SRC (pat)); 209518334Speter 209618334Speter /* See if this is a `movM' pattern, and handle elsewhere if so. */ 209718334Speter 209818334Speter if (*dest != cc0_rtx 209918334Speter && (STACK_REG_P (*src) 210018334Speter || (STACK_REG_P (*dest) 210118334Speter && (GET_CODE (*src) == REG || GET_CODE (*src) == MEM 210218334Speter || GET_CODE (*src) == CONST_DOUBLE)))) 210318334Speter move_for_stack_reg (insn, regstack, pat); 210418334Speter else 210518334Speter switch (GET_CODE (SET_SRC (pat))) 210618334Speter { 210718334Speter case COMPARE: 210818334Speter compare_for_stack_reg (insn, regstack, pat); 210918334Speter break; 211018334Speter 211118334Speter case CALL: 211218334Speter { 211318334Speter int count; 211418334Speter for (count = HARD_REGNO_NREGS (REGNO (*dest), GET_MODE (*dest)); 211518334Speter --count >= 0;) 211618334Speter { 211718334Speter regstack->reg[++regstack->top] = REGNO (*dest) + count; 211818334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count); 211918334Speter } 212018334Speter } 212118334Speter replace_reg (dest, FIRST_STACK_REG); 212218334Speter break; 212318334Speter 212418334Speter case REG: 212518334Speter /* This is a `tstM2' case. */ 212618334Speter if (*dest != cc0_rtx) 212718334Speter abort (); 212818334Speter 212918334Speter src1 = src; 213018334Speter 213118334Speter /* Fall through. */ 213218334Speter 213318334Speter case FLOAT_TRUNCATE: 213418334Speter case SQRT: 213518334Speter case ABS: 213618334Speter case NEG: 213718334Speter /* These insns only operate on the top of the stack. DEST might 213818334Speter be cc0_rtx if we're processing a tstM pattern. Also, it's 213918334Speter possible that the tstM case results in a REG_DEAD note on the 214018334Speter source. */ 214118334Speter 214218334Speter if (src1 == 0) 214318334Speter src1 = get_true_reg (&XEXP (SET_SRC (pat), 0)); 214418334Speter 214518334Speter emit_swap_insn (insn, regstack, *src1); 214618334Speter 214718334Speter src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); 214818334Speter 214918334Speter if (STACK_REG_P (*dest)) 215018334Speter replace_reg (dest, FIRST_STACK_REG); 215118334Speter 215218334Speter if (src1_note) 215318334Speter { 215418334Speter replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); 215518334Speter regstack->top--; 215618334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1)); 215718334Speter } 215818334Speter 215918334Speter replace_reg (src1, FIRST_STACK_REG); 216018334Speter 216118334Speter break; 216218334Speter 216318334Speter case MINUS: 216418334Speter case DIV: 216518334Speter /* On i386, reversed forms of subM3 and divM3 exist for 216618334Speter MODE_FLOAT, so the same code that works for addM3 and mulM3 216718334Speter can be used. */ 216818334Speter case MULT: 216918334Speter case PLUS: 217018334Speter /* These insns can accept the top of stack as a destination 217118334Speter from a stack reg or mem, or can use the top of stack as a 217218334Speter source and some other stack register (possibly top of stack) 217318334Speter as a destination. */ 217418334Speter 217518334Speter src1 = get_true_reg (&XEXP (SET_SRC (pat), 0)); 217618334Speter src2 = get_true_reg (&XEXP (SET_SRC (pat), 1)); 217718334Speter 217818334Speter /* We will fix any death note later. */ 217918334Speter 218018334Speter if (STACK_REG_P (*src1)) 218118334Speter src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); 218218334Speter else 218318334Speter src1_note = NULL_RTX; 218418334Speter if (STACK_REG_P (*src2)) 218518334Speter src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); 218618334Speter else 218718334Speter src2_note = NULL_RTX; 218818334Speter 218918334Speter /* If either operand is not a stack register, then the dest 219018334Speter must be top of stack. */ 219118334Speter 219218334Speter if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2)) 219318334Speter emit_swap_insn (insn, regstack, *dest); 219418334Speter else 219518334Speter { 219618334Speter /* Both operands are REG. If neither operand is already 219718334Speter at the top of stack, choose to make the one that is the dest 219818334Speter the new top of stack. */ 219918334Speter 220018334Speter int src1_hard_regnum, src2_hard_regnum; 220118334Speter 220218334Speter src1_hard_regnum = get_hard_regnum (regstack, *src1); 220318334Speter src2_hard_regnum = get_hard_regnum (regstack, *src2); 220418334Speter if (src1_hard_regnum == -1 || src2_hard_regnum == -1) 220518334Speter abort (); 220618334Speter 220718334Speter if (src1_hard_regnum != FIRST_STACK_REG 220818334Speter && src2_hard_regnum != FIRST_STACK_REG) 220918334Speter emit_swap_insn (insn, regstack, *dest); 221018334Speter } 221118334Speter 221218334Speter if (STACK_REG_P (*src1)) 221318334Speter replace_reg (src1, get_hard_regnum (regstack, *src1)); 221418334Speter if (STACK_REG_P (*src2)) 221518334Speter replace_reg (src2, get_hard_regnum (regstack, *src2)); 221618334Speter 221718334Speter if (src1_note) 221818334Speter { 221918334Speter /* If the register that dies is at the top of stack, then 222018334Speter the destination is somewhere else - merely substitute it. 222118334Speter But if the reg that dies is not at top of stack, then 222218334Speter move the top of stack to the dead reg, as though we had 222318334Speter done the insn and then a store-with-pop. */ 222418334Speter 222518334Speter if (REGNO (XEXP (src1_note, 0)) == regstack->reg[regstack->top]) 222618334Speter { 222718334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); 222818334Speter replace_reg (dest, get_hard_regnum (regstack, *dest)); 222918334Speter } 223018334Speter else 223118334Speter { 223218334Speter int regno = get_hard_regnum (regstack, XEXP (src1_note, 0)); 223318334Speter 223418334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); 223518334Speter replace_reg (dest, regno); 223618334Speter 223718334Speter regstack->reg[regstack->top - (regno - FIRST_STACK_REG)] 223818334Speter = regstack->reg[regstack->top]; 223918334Speter } 224018334Speter 224118334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, 224218334Speter REGNO (XEXP (src1_note, 0))); 224318334Speter replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); 224418334Speter regstack->top--; 224518334Speter } 224618334Speter else if (src2_note) 224718334Speter { 224818334Speter if (REGNO (XEXP (src2_note, 0)) == regstack->reg[regstack->top]) 224918334Speter { 225018334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); 225118334Speter replace_reg (dest, get_hard_regnum (regstack, *dest)); 225218334Speter } 225318334Speter else 225418334Speter { 225518334Speter int regno = get_hard_regnum (regstack, XEXP (src2_note, 0)); 225618334Speter 225718334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); 225818334Speter replace_reg (dest, regno); 225918334Speter 226018334Speter regstack->reg[regstack->top - (regno - FIRST_STACK_REG)] 226118334Speter = regstack->reg[regstack->top]; 226218334Speter } 226318334Speter 226418334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, 226518334Speter REGNO (XEXP (src2_note, 0))); 226618334Speter replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG); 226718334Speter regstack->top--; 226818334Speter } 226918334Speter else 227018334Speter { 227118334Speter SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest)); 227218334Speter replace_reg (dest, get_hard_regnum (regstack, *dest)); 227318334Speter } 227418334Speter 227518334Speter break; 227618334Speter 227718334Speter case UNSPEC: 227818334Speter switch (XINT (SET_SRC (pat), 1)) 227918334Speter { 228018334Speter case 1: /* sin */ 228118334Speter case 2: /* cos */ 228218334Speter /* These insns only operate on the top of the stack. */ 228318334Speter 228418334Speter src1 = get_true_reg (&XVECEXP (SET_SRC (pat), 0, 0)); 228518334Speter 228618334Speter emit_swap_insn (insn, regstack, *src1); 228718334Speter 228818334Speter src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); 228918334Speter 229018334Speter if (STACK_REG_P (*dest)) 229118334Speter replace_reg (dest, FIRST_STACK_REG); 229218334Speter 229318334Speter if (src1_note) 229418334Speter { 229518334Speter replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); 229618334Speter regstack->top--; 229718334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1)); 229818334Speter } 229918334Speter 230018334Speter replace_reg (src1, FIRST_STACK_REG); 230118334Speter 230218334Speter break; 230318334Speter 230418334Speter default: 230518334Speter abort (); 230618334Speter } 230718334Speter break; 230818334Speter 230918334Speter default: 231018334Speter abort (); 231118334Speter } 231218334Speter} 231318334Speter 231418334Speter/* Substitute hard regnums for any stack regs in INSN, which has 231518334Speter N_INPUTS inputs and N_OUTPUTS outputs. REGSTACK is the stack info 231618334Speter before the insn, and is updated with changes made here. CONSTRAINTS is 231718334Speter an array of the constraint strings used in the asm statement. 231818334Speter 231918334Speter OPERANDS is an array of the operands, and OPERANDS_LOC is a 232018334Speter parallel array of where the operands were found. The output operands 232118334Speter all precede the input operands. 232218334Speter 232318334Speter There are several requirements and assumptions about the use of 232418334Speter stack-like regs in asm statements. These rules are enforced by 232518334Speter record_asm_stack_regs; see comments there for details. Any 232618334Speter asm_operands left in the RTL at this point may be assume to meet the 232718334Speter requirements, since record_asm_stack_regs removes any problem asm. */ 232818334Speter 232918334Speterstatic void 233018334Spetersubst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints, 233118334Speter n_inputs, n_outputs) 233218334Speter rtx insn; 233318334Speter stack regstack; 233418334Speter rtx *operands, **operands_loc; 233518334Speter char **constraints; 233618334Speter int n_inputs, n_outputs; 233718334Speter{ 233818334Speter int n_operands = n_inputs + n_outputs; 233918334Speter int first_input = n_outputs; 234018334Speter rtx body = PATTERN (insn); 234118334Speter 234218334Speter int *operand_matches = (int *) alloca (n_operands * sizeof (int *)); 234318334Speter enum reg_class *operand_class 234418334Speter = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *)); 234518334Speter 234618334Speter rtx *note_reg; /* Array of note contents */ 234718334Speter rtx **note_loc; /* Address of REG field of each note */ 234818334Speter enum reg_note *note_kind; /* The type of each note */ 234918334Speter 235018334Speter rtx *clobber_reg; 235118334Speter rtx **clobber_loc; 235218334Speter 235318334Speter struct stack_def temp_stack; 235418334Speter int n_notes; 235518334Speter int n_clobbers; 235618334Speter rtx note; 235718334Speter int i; 235818334Speter 235918334Speter /* Find out what the constraints required. If no constraint 236018334Speter alternative matches, that is a compiler bug: we should have caught 236118334Speter such an insn during the life analysis pass (and reload should have 236218334Speter caught it regardless). */ 236318334Speter 236418334Speter i = constrain_asm_operands (n_operands, operands, constraints, 236518334Speter operand_matches, operand_class); 236618334Speter if (i < 0) 236718334Speter abort (); 236818334Speter 236918334Speter /* Strip SUBREGs here to make the following code simpler. */ 237018334Speter for (i = 0; i < n_operands; i++) 237118334Speter if (GET_CODE (operands[i]) == SUBREG 237218334Speter && GET_CODE (SUBREG_REG (operands[i])) == REG) 237318334Speter { 237418334Speter operands_loc[i] = & SUBREG_REG (operands[i]); 237518334Speter operands[i] = SUBREG_REG (operands[i]); 237618334Speter } 237718334Speter 237818334Speter /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND. */ 237918334Speter 238018334Speter for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1)) 238118334Speter i++; 238218334Speter 238318334Speter note_reg = (rtx *) alloca (i * sizeof (rtx)); 238418334Speter note_loc = (rtx **) alloca (i * sizeof (rtx *)); 238518334Speter note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note)); 238618334Speter 238718334Speter n_notes = 0; 238818334Speter for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) 238918334Speter { 239018334Speter rtx reg = XEXP (note, 0); 239118334Speter rtx *loc = & XEXP (note, 0); 239218334Speter 239318334Speter if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG) 239418334Speter { 239518334Speter loc = & SUBREG_REG (reg); 239618334Speter reg = SUBREG_REG (reg); 239718334Speter } 239818334Speter 239918334Speter if (STACK_REG_P (reg) 240018334Speter && (REG_NOTE_KIND (note) == REG_DEAD 240118334Speter || REG_NOTE_KIND (note) == REG_UNUSED)) 240218334Speter { 240318334Speter note_reg[n_notes] = reg; 240418334Speter note_loc[n_notes] = loc; 240518334Speter note_kind[n_notes] = REG_NOTE_KIND (note); 240618334Speter n_notes++; 240718334Speter } 240818334Speter } 240918334Speter 241018334Speter /* Set up CLOBBER_REG and CLOBBER_LOC. */ 241118334Speter 241218334Speter n_clobbers = 0; 241318334Speter 241418334Speter if (GET_CODE (body) == PARALLEL) 241518334Speter { 241618334Speter clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *)); 241718334Speter clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx **)); 241818334Speter 241918334Speter for (i = 0; i < XVECLEN (body, 0); i++) 242018334Speter if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) 242118334Speter { 242218334Speter rtx clobber = XVECEXP (body, 0, i); 242318334Speter rtx reg = XEXP (clobber, 0); 242418334Speter rtx *loc = & XEXP (clobber, 0); 242518334Speter 242618334Speter if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG) 242718334Speter { 242818334Speter loc = & SUBREG_REG (reg); 242918334Speter reg = SUBREG_REG (reg); 243018334Speter } 243118334Speter 243218334Speter if (STACK_REG_P (reg)) 243318334Speter { 243418334Speter clobber_reg[n_clobbers] = reg; 243518334Speter clobber_loc[n_clobbers] = loc; 243618334Speter n_clobbers++; 243718334Speter } 243818334Speter } 243918334Speter } 244018334Speter 244118334Speter bcopy ((char *) regstack, (char *) &temp_stack, sizeof (temp_stack)); 244218334Speter 244318334Speter /* Put the input regs into the desired place in TEMP_STACK. */ 244418334Speter 244518334Speter for (i = first_input; i < first_input + n_inputs; i++) 244618334Speter if (STACK_REG_P (operands[i]) 244718334Speter && reg_class_subset_p (operand_class[i], FLOAT_REGS) 244818334Speter && operand_class[i] != FLOAT_REGS) 244918334Speter { 245018334Speter /* If an operand needs to be in a particular reg in 245118334Speter FLOAT_REGS, the constraint was either 't' or 'u'. Since 245218334Speter these constraints are for single register classes, and reload 245318334Speter guaranteed that operand[i] is already in that class, we can 245418334Speter just use REGNO (operands[i]) to know which actual reg this 245518334Speter operand needs to be in. */ 245618334Speter 245718334Speter int regno = get_hard_regnum (&temp_stack, operands[i]); 245818334Speter 245918334Speter if (regno < 0) 246018334Speter abort (); 246118334Speter 246218334Speter if (regno != REGNO (operands[i])) 246318334Speter { 246418334Speter /* operands[i] is not in the right place. Find it 246518334Speter and swap it with whatever is already in I's place. 246618334Speter K is where operands[i] is now. J is where it should 246718334Speter be. */ 246818334Speter int j, k, temp; 246918334Speter 247018334Speter k = temp_stack.top - (regno - FIRST_STACK_REG); 247118334Speter j = (temp_stack.top 247218334Speter - (REGNO (operands[i]) - FIRST_STACK_REG)); 247318334Speter 247418334Speter temp = temp_stack.reg[k]; 247518334Speter temp_stack.reg[k] = temp_stack.reg[j]; 247618334Speter temp_stack.reg[j] = temp; 247718334Speter } 247818334Speter } 247918334Speter 248018334Speter /* emit insns before INSN to make sure the reg-stack is in the right 248118334Speter order. */ 248218334Speter 248318334Speter change_stack (insn, regstack, &temp_stack, emit_insn_before); 248418334Speter 248518334Speter /* Make the needed input register substitutions. Do death notes and 248618334Speter clobbers too, because these are for inputs, not outputs. */ 248718334Speter 248818334Speter for (i = first_input; i < first_input + n_inputs; i++) 248918334Speter if (STACK_REG_P (operands[i])) 249018334Speter { 249118334Speter int regnum = get_hard_regnum (regstack, operands[i]); 249218334Speter 249318334Speter if (regnum < 0) 249418334Speter abort (); 249518334Speter 249618334Speter replace_reg (operands_loc[i], regnum); 249718334Speter } 249818334Speter 249918334Speter for (i = 0; i < n_notes; i++) 250018334Speter if (note_kind[i] == REG_DEAD) 250118334Speter { 250218334Speter int regnum = get_hard_regnum (regstack, note_reg[i]); 250318334Speter 250418334Speter if (regnum < 0) 250518334Speter abort (); 250618334Speter 250718334Speter replace_reg (note_loc[i], regnum); 250818334Speter } 250918334Speter 251018334Speter for (i = 0; i < n_clobbers; i++) 251118334Speter { 251218334Speter /* It's OK for a CLOBBER to reference a reg that is not live. 251318334Speter Don't try to replace it in that case. */ 251418334Speter int regnum = get_hard_regnum (regstack, clobber_reg[i]); 251518334Speter 251618334Speter if (regnum >= 0) 251718334Speter { 251818334Speter /* Sigh - clobbers always have QImode. But replace_reg knows 251918334Speter that these regs can't be MODE_INT and will abort. Just put 252018334Speter the right reg there without calling replace_reg. */ 252118334Speter 252218334Speter *clobber_loc[i] = FP_MODE_REG (regnum, DFmode); 252318334Speter } 252418334Speter } 252518334Speter 252618334Speter /* Now remove from REGSTACK any inputs that the asm implicitly popped. */ 252718334Speter 252818334Speter for (i = first_input; i < first_input + n_inputs; i++) 252918334Speter if (STACK_REG_P (operands[i])) 253018334Speter { 253118334Speter /* An input reg is implicitly popped if it is tied to an 253218334Speter output, or if there is a CLOBBER for it. */ 253318334Speter int j; 253418334Speter 253518334Speter for (j = 0; j < n_clobbers; j++) 253618334Speter if (operands_match_p (clobber_reg[j], operands[i])) 253718334Speter break; 253818334Speter 253918334Speter if (j < n_clobbers || operand_matches[i] >= 0) 254018334Speter { 254118334Speter /* operands[i] might not be at the top of stack. But that's OK, 254218334Speter because all we need to do is pop the right number of regs 254318334Speter off of the top of the reg-stack. record_asm_stack_regs 254418334Speter guaranteed that all implicitly popped regs were grouped 254518334Speter at the top of the reg-stack. */ 254618334Speter 254718334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, 254818334Speter regstack->reg[regstack->top]); 254918334Speter regstack->top--; 255018334Speter } 255118334Speter } 255218334Speter 255318334Speter /* Now add to REGSTACK any outputs that the asm implicitly pushed. 255418334Speter Note that there isn't any need to substitute register numbers. 255518334Speter ??? Explain why this is true. */ 255618334Speter 255718334Speter for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--) 255818334Speter { 255918334Speter /* See if there is an output for this hard reg. */ 256018334Speter int j; 256118334Speter 256218334Speter for (j = 0; j < n_outputs; j++) 256318334Speter if (STACK_REG_P (operands[j]) && REGNO (operands[j]) == i) 256418334Speter { 256518334Speter regstack->reg[++regstack->top] = i; 256618334Speter SET_HARD_REG_BIT (regstack->reg_set, i); 256718334Speter break; 256818334Speter } 256918334Speter } 257018334Speter 257118334Speter /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD 257218334Speter input that the asm didn't implicitly pop. If the asm didn't 257318334Speter implicitly pop an input reg, that reg will still be live. 257418334Speter 257518334Speter Note that we can't use find_regno_note here: the register numbers 257618334Speter in the death notes have already been substituted. */ 257718334Speter 257818334Speter for (i = 0; i < n_outputs; i++) 257918334Speter if (STACK_REG_P (operands[i])) 258018334Speter { 258118334Speter int j; 258218334Speter 258318334Speter for (j = 0; j < n_notes; j++) 258418334Speter if (REGNO (operands[i]) == REGNO (note_reg[j]) 258518334Speter && note_kind[j] == REG_UNUSED) 258618334Speter { 258718334Speter insn = emit_pop_insn (insn, regstack, operands[i], 258818334Speter emit_insn_after); 258918334Speter break; 259018334Speter } 259118334Speter } 259218334Speter 259318334Speter for (i = first_input; i < first_input + n_inputs; i++) 259418334Speter if (STACK_REG_P (operands[i])) 259518334Speter { 259618334Speter int j; 259718334Speter 259818334Speter for (j = 0; j < n_notes; j++) 259918334Speter if (REGNO (operands[i]) == REGNO (note_reg[j]) 260018334Speter && note_kind[j] == REG_DEAD 260118334Speter && TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]))) 260218334Speter { 260318334Speter insn = emit_pop_insn (insn, regstack, operands[i], 260418334Speter emit_insn_after); 260518334Speter break; 260618334Speter } 260718334Speter } 260818334Speter} 260918334Speter 261018334Speter/* Substitute stack hard reg numbers for stack virtual registers in 261118334Speter INSN. Non-stack register numbers are not changed. REGSTACK is the 261218334Speter current stack content. Insns may be emitted as needed to arrange the 261318334Speter stack for the 387 based on the contents of the insn. */ 261418334Speter 261518334Speterstatic void 261618334Spetersubst_stack_regs (insn, regstack) 261718334Speter rtx insn; 261818334Speter stack regstack; 261918334Speter{ 262018334Speter register rtx *note_link, note; 262118334Speter register int i; 262218334Speter int n_operands; 262318334Speter 262418334Speter if (GET_CODE (insn) == CALL_INSN) 262518334Speter { 262618334Speter int top = regstack->top; 262718334Speter 262818334Speter /* If there are any floating point parameters to be passed in 262918334Speter registers for this call, make sure they are in the right 263018334Speter order. */ 263118334Speter 263218334Speter if (top >= 0) 263318334Speter { 263418334Speter straighten_stack (PREV_INSN (insn), regstack); 263518334Speter 263618334Speter /* Now mark the arguments as dead after the call. */ 263718334Speter 263818334Speter while (regstack->top >= 0) 263918334Speter { 264018334Speter CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top); 264118334Speter regstack->top--; 264218334Speter } 264318334Speter } 264418334Speter } 264518334Speter 264618334Speter /* Do the actual substitution if any stack regs are mentioned. 264718334Speter Since we only record whether entire insn mentions stack regs, and 264818334Speter subst_stack_regs_pat only works for patterns that contain stack regs, 264918334Speter we must check each pattern in a parallel here. A call_value_pop could 265018334Speter fail otherwise. */ 265118334Speter 265218334Speter if (GET_MODE (insn) == QImode) 265318334Speter { 265418334Speter n_operands = asm_noperands (PATTERN (insn)); 265518334Speter if (n_operands >= 0) 265618334Speter { 265718334Speter /* This insn is an `asm' with operands. Decode the operands, 265818334Speter decide how many are inputs, and do register substitution. 265918334Speter Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */ 266018334Speter 266118334Speter rtx operands[MAX_RECOG_OPERANDS]; 266218334Speter rtx *operands_loc[MAX_RECOG_OPERANDS]; 266318334Speter rtx body = PATTERN (insn); 266418334Speter int n_inputs, n_outputs; 266518334Speter char **constraints 266618334Speter = (char **) alloca (n_operands * sizeof (char *)); 266718334Speter 266818334Speter decode_asm_operands (body, operands, operands_loc, 266918334Speter constraints, NULL_PTR); 267018334Speter get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs); 267118334Speter subst_asm_stack_regs (insn, regstack, operands, operands_loc, 267218334Speter constraints, n_inputs, n_outputs); 267318334Speter return; 267418334Speter } 267518334Speter 267618334Speter if (GET_CODE (PATTERN (insn)) == PARALLEL) 267718334Speter for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) 267818334Speter { 267918334Speter if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i))) 268018334Speter subst_stack_regs_pat (insn, regstack, 268118334Speter XVECEXP (PATTERN (insn), 0, i)); 268218334Speter } 268318334Speter else 268418334Speter subst_stack_regs_pat (insn, regstack, PATTERN (insn)); 268518334Speter } 268618334Speter 268718334Speter /* subst_stack_regs_pat may have deleted a no-op insn. If so, any 268818334Speter REG_UNUSED will already have been dealt with, so just return. */ 268918334Speter 269018334Speter if (GET_CODE (insn) == NOTE) 269118334Speter return; 269218334Speter 269318334Speter /* If there is a REG_UNUSED note on a stack register on this insn, 269418334Speter the indicated reg must be popped. The REG_UNUSED note is removed, 269518334Speter since the form of the newly emitted pop insn references the reg, 269618334Speter making it no longer `unset'. */ 269718334Speter 269818334Speter note_link = ®_NOTES(insn); 269918334Speter for (note = *note_link; note; note = XEXP (note, 1)) 270018334Speter if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0))) 270118334Speter { 270218334Speter *note_link = XEXP (note, 1); 270318334Speter insn = emit_pop_insn (insn, regstack, XEXP (note, 0), emit_insn_after); 270418334Speter } 270518334Speter else 270618334Speter note_link = &XEXP (note, 1); 270718334Speter} 270818334Speter 270918334Speter/* Change the organization of the stack so that it fits a new basic 271018334Speter block. Some registers might have to be popped, but there can never be 271118334Speter a register live in the new block that is not now live. 271218334Speter 271318334Speter Insert any needed insns before or after INSN. WHEN is emit_insn_before 271418334Speter or emit_insn_after. OLD is the original stack layout, and NEW is 271518334Speter the desired form. OLD is updated to reflect the code emitted, ie, it 271618334Speter will be the same as NEW upon return. 271718334Speter 271818334Speter This function will not preserve block_end[]. But that information 271918334Speter is no longer needed once this has executed. */ 272018334Speter 272118334Speterstatic void 272218334Speterchange_stack (insn, old, new, when) 272318334Speter rtx insn; 272418334Speter stack old; 272518334Speter stack new; 272618334Speter rtx (*when)(); 272718334Speter{ 272818334Speter int reg; 272918334Speter 273018334Speter /* We will be inserting new insns "backwards", by calling emit_insn_before. 273118334Speter If we are to insert after INSN, find the next insn, and insert before 273218334Speter it. */ 273318334Speter 273418334Speter if (when == emit_insn_after) 273518334Speter insn = NEXT_INSN (insn); 273618334Speter 273718334Speter /* Pop any registers that are not needed in the new block. */ 273818334Speter 273918334Speter for (reg = old->top; reg >= 0; reg--) 274018334Speter if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg])) 274118334Speter emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode), 274218334Speter emit_insn_before); 274318334Speter 274418334Speter if (new->top == -2) 274518334Speter { 274618334Speter /* If the new block has never been processed, then it can inherit 274718334Speter the old stack order. */ 274818334Speter 274918334Speter new->top = old->top; 275018334Speter bcopy (old->reg, new->reg, sizeof (new->reg)); 275118334Speter } 275218334Speter else 275318334Speter { 275418334Speter /* This block has been entered before, and we must match the 275518334Speter previously selected stack order. */ 275618334Speter 275718334Speter /* By now, the only difference should be the order of the stack, 275818334Speter not their depth or liveliness. */ 275918334Speter 276018334Speter GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win); 276118334Speter 276218334Speter abort (); 276318334Speter 276418334Speter win: 276518334Speter 276618334Speter if (old->top != new->top) 276718334Speter abort (); 276818334Speter 276918334Speter /* Loop here emitting swaps until the stack is correct. The 277018334Speter worst case number of swaps emitted is N + 2, where N is the 277118334Speter depth of the stack. In some cases, the reg at the top of 277218334Speter stack may be correct, but swapped anyway in order to fix 277318334Speter other regs. But since we never swap any other reg away from 277418334Speter its correct slot, this algorithm will converge. */ 277518334Speter 277618334Speter do 277718334Speter { 277818334Speter /* Swap the reg at top of stack into the position it is 277918334Speter supposed to be in, until the correct top of stack appears. */ 278018334Speter 278118334Speter while (old->reg[old->top] != new->reg[new->top]) 278218334Speter { 278318334Speter for (reg = new->top; reg >= 0; reg--) 278418334Speter if (new->reg[reg] == old->reg[old->top]) 278518334Speter break; 278618334Speter 278718334Speter if (reg == -1) 278818334Speter abort (); 278918334Speter 279018334Speter emit_swap_insn (insn, old, 279118334Speter FP_MODE_REG (old->reg[reg], DFmode)); 279218334Speter } 279318334Speter 279418334Speter /* See if any regs remain incorrect. If so, bring an 279518334Speter incorrect reg to the top of stack, and let the while loop 279618334Speter above fix it. */ 279718334Speter 279818334Speter for (reg = new->top; reg >= 0; reg--) 279918334Speter if (new->reg[reg] != old->reg[reg]) 280018334Speter { 280118334Speter emit_swap_insn (insn, old, 280218334Speter FP_MODE_REG (old->reg[reg], DFmode)); 280318334Speter break; 280418334Speter } 280518334Speter } while (reg >= 0); 280618334Speter 280718334Speter /* At this point there must be no differences. */ 280818334Speter 280918334Speter for (reg = old->top; reg >= 0; reg--) 281018334Speter if (old->reg[reg] != new->reg[reg]) 281118334Speter abort (); 281218334Speter } 281318334Speter} 281418334Speter 281518334Speter/* Check PAT, which points to RTL in INSN, for a LABEL_REF. If it is 281618334Speter found, ensure that a jump from INSN to the code_label to which the 281718334Speter label_ref points ends up with the same stack as that at the 281818334Speter code_label. Do this by inserting insns just before the code_label to 281918334Speter pop and rotate the stack until it is in the correct order. REGSTACK 282018334Speter is the order of the register stack in INSN. 282118334Speter 282218334Speter Any code that is emitted here must not be later processed as part 282318334Speter of any block, as it will already contain hard register numbers. */ 282418334Speter 282518334Speterstatic void 282618334Spetergoto_block_pat (insn, regstack, pat) 282718334Speter rtx insn; 282818334Speter stack regstack; 282918334Speter rtx pat; 283018334Speter{ 283118334Speter rtx label; 283218334Speter rtx new_jump, new_label, new_barrier; 283318334Speter rtx *ref; 283418334Speter stack label_stack; 283518334Speter struct stack_def temp_stack; 283618334Speter int reg; 283718334Speter 283818334Speter switch (GET_CODE (pat)) 283918334Speter { 284018334Speter case RETURN: 284118334Speter straighten_stack (PREV_INSN (insn), regstack); 284218334Speter return; 284318334Speter default: 284418334Speter { 284518334Speter int i, j; 284618334Speter char *fmt = GET_RTX_FORMAT (GET_CODE (pat)); 284718334Speter 284818334Speter for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) 284918334Speter { 285018334Speter if (fmt[i] == 'e') 285118334Speter goto_block_pat (insn, regstack, XEXP (pat, i)); 285218334Speter if (fmt[i] == 'E') 285318334Speter for (j = 0; j < XVECLEN (pat, i); j++) 285418334Speter goto_block_pat (insn, regstack, XVECEXP (pat, i, j)); 285518334Speter } 285618334Speter return; 285718334Speter } 285818334Speter case LABEL_REF:; 285918334Speter } 286018334Speter 286118334Speter label = XEXP (pat, 0); 286218334Speter if (GET_CODE (label) != CODE_LABEL) 286318334Speter abort (); 286418334Speter 286518334Speter /* First, see if in fact anything needs to be done to the stack at all. */ 286618334Speter if (INSN_UID (label) <= 0) 286718334Speter return; 286818334Speter 286918334Speter label_stack = &block_stack_in[BLOCK_NUM (label)]; 287018334Speter 287118334Speter if (label_stack->top == -2) 287218334Speter { 287318334Speter /* If the target block hasn't had a stack order selected, then 287418334Speter we need merely ensure that no pops are needed. */ 287518334Speter 287618334Speter for (reg = regstack->top; reg >= 0; reg--) 287718334Speter if (! TEST_HARD_REG_BIT (label_stack->reg_set, regstack->reg[reg])) 287818334Speter break; 287918334Speter 288018334Speter if (reg == -1) 288118334Speter { 288218334Speter /* change_stack will not emit any code in this case. */ 288318334Speter 288418334Speter change_stack (label, regstack, label_stack, emit_insn_after); 288518334Speter return; 288618334Speter } 288718334Speter } 288818334Speter else if (label_stack->top == regstack->top) 288918334Speter { 289018334Speter for (reg = label_stack->top; reg >= 0; reg--) 289118334Speter if (label_stack->reg[reg] != regstack->reg[reg]) 289218334Speter break; 289318334Speter 289418334Speter if (reg == -1) 289518334Speter return; 289618334Speter } 289718334Speter 289818334Speter /* At least one insn will need to be inserted before label. Insert 289918334Speter a jump around the code we are about to emit. Emit a label for the new 290018334Speter code, and point the original insn at this new label. We can't use 290118334Speter redirect_jump here, because we're using fld[4] of the code labels as 290218334Speter LABEL_REF chains, no NUSES counters. */ 290318334Speter 290418334Speter new_jump = emit_jump_insn_before (gen_jump (label), label); 290518334Speter record_label_references (new_jump, PATTERN (new_jump)); 290618334Speter JUMP_LABEL (new_jump) = label; 290718334Speter 290818334Speter new_barrier = emit_barrier_after (new_jump); 290918334Speter 291018334Speter new_label = gen_label_rtx (); 291118334Speter emit_label_after (new_label, new_barrier); 291218334Speter LABEL_REFS (new_label) = new_label; 291318334Speter 291418334Speter /* The old label_ref will no longer point to the code_label if now uses, 291518334Speter so strip the label_ref from the code_label's chain of references. */ 291618334Speter 291718334Speter for (ref = &LABEL_REFS (label); *ref != label; ref = &LABEL_NEXTREF (*ref)) 291818334Speter if (*ref == pat) 291918334Speter break; 292018334Speter 292118334Speter if (*ref == label) 292218334Speter abort (); 292318334Speter 292418334Speter *ref = LABEL_NEXTREF (*ref); 292518334Speter 292618334Speter XEXP (pat, 0) = new_label; 292718334Speter record_label_references (insn, PATTERN (insn)); 292818334Speter 292918334Speter if (JUMP_LABEL (insn) == label) 293018334Speter JUMP_LABEL (insn) = new_label; 293118334Speter 293218334Speter /* Now emit the needed code. */ 293318334Speter 293418334Speter temp_stack = *regstack; 293518334Speter 293618334Speter change_stack (new_label, &temp_stack, label_stack, emit_insn_after); 293718334Speter} 293818334Speter 293918334Speter/* Traverse all basic blocks in a function, converting the register 294018334Speter references in each insn from the "flat" register file that gcc uses, to 294118334Speter the stack-like registers the 387 uses. */ 294218334Speter 294318334Speterstatic void 294418334Speterconvert_regs () 294518334Speter{ 294618334Speter register int block, reg; 294718334Speter register rtx insn, next; 294818334Speter struct stack_def regstack; 294918334Speter 295018334Speter for (block = 0; block < blocks; block++) 295118334Speter { 295218334Speter if (block_stack_in[block].top == -2) 295318334Speter { 295418334Speter /* This block has not been previously encountered. Choose a 295518334Speter default mapping for any stack regs live on entry */ 295618334Speter 295718334Speter block_stack_in[block].top = -1; 295818334Speter 295918334Speter for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--) 296018334Speter if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, reg)) 296118334Speter block_stack_in[block].reg[++block_stack_in[block].top] = reg; 296218334Speter } 296318334Speter 296418334Speter /* Process all insns in this block. Keep track of `next' here, 296518334Speter so that we don't process any insns emitted while making 296618334Speter substitutions in INSN. */ 296718334Speter 296818334Speter next = block_begin[block]; 296918334Speter regstack = block_stack_in[block]; 297018334Speter do 297118334Speter { 297218334Speter insn = next; 297318334Speter next = NEXT_INSN (insn); 297418334Speter 297518334Speter /* Don't bother processing unless there is a stack reg 297618334Speter mentioned or if it's a CALL_INSN (register passing of 297718334Speter floating point values). */ 297818334Speter 297918334Speter if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN) 298018334Speter subst_stack_regs (insn, ®stack); 298118334Speter 298218334Speter } while (insn != block_end[block]); 298318334Speter 298418334Speter /* Something failed if the stack life doesn't match. */ 298518334Speter 298618334Speter GO_IF_HARD_REG_EQUAL (regstack.reg_set, block_out_reg_set[block], win); 298718334Speter 298818334Speter abort (); 298918334Speter 299018334Speter win: 299118334Speter 299218334Speter /* Adjust the stack of this block on exit to match the stack of 299318334Speter the target block, or copy stack information into stack of 299418334Speter jump target if the target block's stack order hasn't been set 299518334Speter yet. */ 299618334Speter 299718334Speter if (GET_CODE (insn) == JUMP_INSN) 299818334Speter goto_block_pat (insn, ®stack, PATTERN (insn)); 299918334Speter 300018334Speter /* Likewise handle the case where we fall into the next block. */ 300118334Speter 300218334Speter if ((block < blocks - 1) && block_drops_in[block+1]) 300318334Speter change_stack (insn, ®stack, &block_stack_in[block+1], 300418334Speter emit_insn_after); 300518334Speter } 300618334Speter 300718334Speter /* If the last basic block is the end of a loop, and that loop has 300818334Speter regs live at its start, then the last basic block will have regs live 300918334Speter at its end that need to be popped before the function returns. */ 301018334Speter 301118334Speter { 301218334Speter int value_reg_low, value_reg_high; 301318334Speter value_reg_low = value_reg_high = -1; 301418334Speter { 301518334Speter rtx retvalue; 301618334Speter if (retvalue = stack_result (current_function_decl)) 301718334Speter { 301818334Speter value_reg_low = REGNO (retvalue); 301918334Speter value_reg_high = value_reg_low + 302018334Speter HARD_REGNO_NREGS (value_reg_low, GET_MODE (retvalue)) - 1; 302118334Speter } 302218334Speter 302318334Speter } 302418334Speter for (reg = regstack.top; reg >= 0; reg--) 302518334Speter if (regstack.reg[reg] < value_reg_low || 302618334Speter regstack.reg[reg] > value_reg_high) 302718334Speter insn = emit_pop_insn (insn, ®stack, 302818334Speter FP_MODE_REG (regstack.reg[reg], DFmode), 302918334Speter emit_insn_after); 303018334Speter } 303118334Speter straighten_stack (insn, ®stack); 303218334Speter} 303318334Speter 303418334Speter/* Check expression PAT, which is in INSN, for label references. if 303518334Speter one is found, print the block number of destination to FILE. */ 303618334Speter 303718334Speterstatic void 303818334Speterprint_blocks (file, insn, pat) 303918334Speter FILE *file; 304018334Speter rtx insn, pat; 304118334Speter{ 304218334Speter register RTX_CODE code = GET_CODE (pat); 304318334Speter register int i; 304418334Speter register char *fmt; 304518334Speter 304618334Speter if (code == LABEL_REF) 304718334Speter { 304818334Speter register rtx label = XEXP (pat, 0); 304918334Speter 305018334Speter if (GET_CODE (label) != CODE_LABEL) 305118334Speter abort (); 305218334Speter 305318334Speter fprintf (file, " %d", BLOCK_NUM (label)); 305418334Speter 305518334Speter return; 305618334Speter } 305718334Speter 305818334Speter fmt = GET_RTX_FORMAT (code); 305918334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 306018334Speter { 306118334Speter if (fmt[i] == 'e') 306218334Speter print_blocks (file, insn, XEXP (pat, i)); 306318334Speter if (fmt[i] == 'E') 306418334Speter { 306518334Speter register int j; 306618334Speter for (j = 0; j < XVECLEN (pat, i); j++) 306718334Speter print_blocks (file, insn, XVECEXP (pat, i, j)); 306818334Speter } 306918334Speter } 307018334Speter} 307118334Speter 307218334Speter/* Write information about stack registers and stack blocks into FILE. 307318334Speter This is part of making a debugging dump. */ 307418334Speterstatic void 307518334Speterdump_stack_info (file) 307618334Speter FILE *file; 307718334Speter{ 307818334Speter register int block; 307918334Speter 308018334Speter fprintf (file, "\n%d stack blocks.\n", blocks); 308118334Speter for (block = 0; block < blocks; block++) 308218334Speter { 308318334Speter register rtx head, jump, end; 308418334Speter register int regno; 308518334Speter 308618334Speter fprintf (file, "\nStack block %d: first insn %d, last %d.\n", 308718334Speter block, INSN_UID (block_begin[block]), 308818334Speter INSN_UID (block_end[block])); 308918334Speter 309018334Speter head = block_begin[block]; 309118334Speter 309218334Speter fprintf (file, "Reached from blocks: "); 309318334Speter if (GET_CODE (head) == CODE_LABEL) 309418334Speter for (jump = LABEL_REFS (head); 309518334Speter jump != head; 309618334Speter jump = LABEL_NEXTREF (jump)) 309718334Speter { 309818334Speter register int from_block = BLOCK_NUM (CONTAINING_INSN (jump)); 309918334Speter fprintf (file, " %d", from_block); 310018334Speter } 310118334Speter if (block_drops_in[block]) 310218334Speter fprintf (file, " previous"); 310318334Speter 310418334Speter fprintf (file, "\nlive stack registers on block entry: "); 310518334Speter for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++) 310618334Speter { 310718334Speter if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, regno)) 310818334Speter fprintf (file, "%d ", regno); 310918334Speter } 311018334Speter 311118334Speter fprintf (file, "\nlive stack registers on block exit: "); 311218334Speter for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++) 311318334Speter { 311418334Speter if (TEST_HARD_REG_BIT (block_out_reg_set[block], regno)) 311518334Speter fprintf (file, "%d ", regno); 311618334Speter } 311718334Speter 311818334Speter end = block_end[block]; 311918334Speter 312018334Speter fprintf (file, "\nJumps to blocks: "); 312118334Speter if (GET_CODE (end) == JUMP_INSN) 312218334Speter print_blocks (file, end, PATTERN (end)); 312318334Speter 312418334Speter if (block + 1 < blocks && block_drops_in[block+1]) 312518334Speter fprintf (file, " next"); 312618334Speter else if (block + 1 == blocks 312718334Speter || (GET_CODE (end) == JUMP_INSN 312818334Speter && GET_CODE (PATTERN (end)) == RETURN)) 312918334Speter fprintf (file, " return"); 313018334Speter 313118334Speter fprintf (file, "\n"); 313218334Speter } 313318334Speter} 313418334Speter#endif /* STACK_REGS */ 3135