00001 # include <stdio.h>
00002 # include "../parm.h"
00003 # include "op_codes.h"
00004 # include "codegen.h"
00005 # include "datatypes/consnodes.h"
00006
00007
00008
00009
00010
00011
00012 static ConsNode * equiv_regs;
00013
00014
00015
00016
00017 static boolean is_this_arg(reg)
00018 unsigned reg;
00019 {
00020 register ConsNode * p;
00021
00022 {
00023 for (p = equiv_regs; p != NIL; p = cn_tail(p)) {
00024 if ((unsigned)(cn_head(p)) == reg) {
00025 return(TRUE);
00026 }
00027 }
00028 return(FALSE);
00029 }
00030 }
00031
00032 void clear_equiv_regs()
00033 {
00034 register ConsNode *p;
00035
00036 p = equiv_regs;
00037 while (p != NIL) {
00038 p = cn_del_hd(p);
00039 }
00040 equiv_regs = NIL;
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 boolean find_equiv_regs(code, n)
00050 struct RIC_instr * code;
00051 int n;
00052 {
00053 register struct RIC_instr *p;
00054 register int i;
00055 unsigned this_arg = n | ARG_BIT;
00056 boolean equiv_regs_changed;
00057
00058 equiv_regs = cn_cons(this_arg, NIL);
00059 do {
00060 equiv_regs_changed = FALSE;
00061 for (p = code; p != RIC_nil; p = p -> next_instr) {
00062 if (p -> op_code == MOV) {
00063 if (is_this_arg(p -> arg[0]) && p -> arg[1] != SK) {
00064 # ifdef DEBUG
00065 if ((p -> arg[1]) & ARG_BIT) {
00066 dbgmsg("only_indirect_ref: clobbered argument\n");
00067 }
00068 # endif
00069 if (p -> arg[1] == RS
00070 || p -> arg[1] < FIRST_AVAIL_LOC
00071 && p -> arg[1] != T1
00072 && p -> arg[1] != T2) {
00073
00074 return(FALSE);
00075 }
00076 if (!is_this_arg(p -> arg[1])) {
00077 equiv_regs_changed = TRUE;
00078 equiv_regs = cn_cons(p -> arg[1], equiv_regs);
00079 }
00080 }
00081 }
00082 }
00083 } while (equiv_regs_changed);
00084 return(TRUE);
00085 }
00086
00087
00088
00089
00090
00091 boolean only_indirect_ref(code, n)
00092 struct RIC_instr * code;
00093 int n;
00094 {
00095 register struct RIC_instr *p;
00096
00097 if (!find_equiv_regs(code, n)) {
00098 return(FALSE);
00099 }
00100 for (p = code; p != RIC_nil; p = p -> next_instr) {
00101 if (!p -> label_arg) {
00102 switch(p -> op_code) {
00103 case LDI:
00104 case STI:
00105 if (is_this_arg(p -> arg[2])
00106 || is_this_arg(p -> arg[0]) && p -> arg[1] != 0) {
00107 return(FALSE);
00108 }
00109 break;
00110 case MOV:
00111 if (!is_this_arg(p -> arg[0])
00112 && is_this_arg(p -> arg[1])) {
00113
00114 return(FALSE);
00115 }
00116 break;
00117 case LDN:
00118 if (is_this_arg(p -> arg[1])) {
00119 return(FALSE);
00120 }
00121 case DCL:
00122 case UDC:
00123 break;
00124 default:
00125 if (is_this_arg(p -> arg[0])
00126 || is_this_arg(p -> arg[1])
00127 || is_this_arg(p -> arg[2])) {
00128 return(FALSE);
00129 }
00130 }
00131 }
00132 }
00133 clear_equiv_regs();
00134 return(TRUE);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 struct RIC_instr * unindirect(code, n, m)
00147 struct RIC_instr * code;
00148 int n;
00149 long m;
00150 {
00151 register struct RIC_instr *p;
00152 register struct RIC_instr **ptr_p;
00153 struct RIC_instr *result;
00154 unsigned this_arg = n | ARG_BIT;
00155
00156 if (!find_equiv_regs(code, n)) {
00157 dbgmsg("Unindirect: code argument inappropriate\n");
00158 }
00159 result = copy_RIC(code);
00160 for (p = result, ptr_p = &result; p != RIC_nil;
00161 ptr_p = &(p -> next_instr), p = p -> next_instr) {
00162 if (!p -> label_arg) {
00163 # ifdef TRACE
00164 extern char * op_code_table[];
00165 printf("%s %d %d %d\n", op_code_table[p -> op_code],
00166 p -> arg[0], p -> arg[1], p -> arg[2]);
00167 # endif
00168 switch(p -> op_code) {
00169 case LDI:
00170 if (is_this_arg(p -> arg[0])) {
00171
00172
00173 p -> op_code = MOV;
00174 p -> arg[0] = m;
00175 p -> arg[1] = p -> arg[2];
00176 p -> arg[2] = SK;
00177 p -> n_args = 2;
00178 }
00179 break;
00180 case STI:
00181 if (is_this_arg(p -> arg[0])) {
00182
00183
00184 p -> op_code = MOV;
00185 p -> arg[0] = p -> arg[2];
00186 p -> arg[1] = m;
00187 p -> arg[2] = SK;
00188 p -> n_args = 2;
00189 }
00190 break;
00191 case MOV:
00192 if (is_this_arg(p -> arg[0])) {
00193
00194
00195 *ptr_p = p -> next_instr;
00196
00197
00198 }
00199 break;
00200
00201 }
00202 }
00203 }
00204 clear_equiv_regs();
00205 return(result);
00206 }
00207
00208