00001 # define DEBUG
00002
00003 # include "parm.h"
00004 # include <stdio.h>
00005 # include "stree/ststructs.mh"
00006 # include "codegen.h"
00007 # include "op_codes.h"
00008 # include "pass4/sigs.h"
00009 # include "pass3/is_local.h"
00010 # include <ctype.h>
00011
00012 extern int yydebug;
00013 extern int yynerrs;
00014
00015 extern FILE * unparse_file;
00016
00017 extern FILE * Goutfile;
00018
00019 extern char str_code_buf[];
00020
00021 extern int avail_loc;
00022
00023 extern int Glevel;
00024
00025 extern NODE * Gcurrent;
00026
00027 extern boolean Vflag;
00028
00029 extern boolean Nflag;
00030
00031 extern boolean Oflag;
00032
00033 extern boolean xflag;
00034
00035
00036 boolean valid_C_id(s)
00037 char * s;
00038 {
00039 register char * t = s;
00040
00041 if (!isalpha(*t) && *t != '_') {
00042 return(FALSE);
00043 };
00044 for (t++; *t != '\0'; t++) {
00045 if (!isalnum(*t) && *t != '_') {
00046 return(FALSE);
00047 }
00048 };
00049 return(TRUE);
00050 }
00051
00052
00053
00054
00055
00056 void compile_stub(nm, sig, lbl, ar_lbl, i)
00057 char * nm;
00058 NODE * sig;
00059 char * lbl;
00060 char * ar_lbl;
00061 int i;
00062 {
00063 int size_loc = avail_loc++;
00064 int ar_loc = avail_loc++;
00065 NODE * params = sig -> fsig_param_list;
00066 int n_args = length(params) - n_vacuous_params(params);
00067 int first_arg_loc;
00068 int closure_loc, tp_loc;
00069 NODE * constr = sig -> fsig_construction;
00070 boolean need_closure = (constr == NIL
00071 || (constr -> fc_complexity & SL_ACC));
00072 boolean discard_ar = (constr != NIL
00073 && (constr -> fc_complexity & NO_AR_REFS));
00074
00075 ASSERT(sig -> kind == FUNCSIGNATURE, "compile_stub: bad sig\n");
00076
00077 sprintf(str_code_buf, "_%s", nm);
00078 genl(EXT, str_code_buf);
00079 genl(BSF, str_code_buf);
00080
00081
00082
00083 first_arg_loc = avail_loc;
00084 avail_loc += n_args;
00085 {
00086 register int arg_count;
00087
00088 for (arg_count = 0; arg_count < n_args; arg_count++) {
00089 gen2(DCL, first_arg_loc + arg_count, DCL_INT);
00090 gen2(GAR, arg_count+1, first_arg_loc + arg_count);
00091 }
00092 }
00093
00094
00095
00096 if (need_closure) {
00097 tp_loc = avail_loc++;
00098 closure_loc = avail_loc++;
00099 gen2(DCL, tp_loc, DCL_ADDR);
00100 gen2(DCL, closure_loc, DCL_ADDR);
00101 genl(LBA, lbl);
00102 gen1(LDL, tp_loc);
00103 gen3(LDI, tp_loc, 0, tp_loc);
00104 gen3(LDI, tp_loc, i, closure_loc);
00105 gen1(UDC, tp_loc);
00106 }
00107
00108 gen2(DCL, size_loc, DCL_INT);
00109 if (constr != NIL) {
00110 gen2(LDN, constr -> ar_size, size_loc);
00111 } else {
00112 gen3(LDI, closure_loc, FO_SIZE, size_loc);
00113 }
00114
00115 gen2(DCL, ar_loc, DCL_ADDR);
00116 gen2(ALH, size_loc, ar_loc);
00117 gen1(UDC, size_loc);
00118
00119
00120 {
00121 register int arg_count;
00122
00123 for (arg_count = 0; arg_count < n_args; arg_count++) {
00124 gen3(STI, ar_loc, arg_count+1, first_arg_loc + arg_count);
00125 gen1(UDC, first_arg_loc + arg_count);
00126 }
00127 }
00128
00129
00130 if (need_closure) {
00131 gen3(LDI, closure_loc, FO_EP, T1);
00132 gen3(STI, ar_loc, 0, T1);
00133 }
00134
00135
00136
00137
00138 # ifndef GEN_C
00139 genl(LBA, ar_lbl);
00140 gen1(LDL, T1);
00141 gen1(HINT, GFU);
00142 gen3(LDI, T1, 0, GF);
00143 # endif
00144
00145 if (!xflag) {
00146
00147 gen2(DCL, T2, DCL_ADDR);
00148 genl(LBA, "_global_ar");
00149 gen1(LDL, T2);
00150 gen3(STI, T2, 0, GF);
00151 gen1(UDC, T2);
00152 } else {
00153
00154
00155 }
00156
00157
00158 gen2(ARG, 1, ar_loc);
00159
00160
00161 if (need_closure) {
00162 gen2(CLI, closure_loc, FO_IP);
00163 gen1(UDC, closure_loc);
00164 } else {
00165 genl(CLL, constr -> fc_code_label);
00166 }
00167
00168
00169 if (discard_ar) {
00170 gen3(HINT, DEA, ar_loc, constr -> ar_size);
00171 }
00172 gen1(UDC, ar_loc);
00173
00174 gen0(RTN);
00175 }
00176
00177
00178
00179
00180
00181
00182 void compile_stubs(tsig, lbl, ar_lbl)
00183 NODE * tsig;
00184 char * lbl;
00185 char * ar_lbl;
00186 {
00187 unsigned * s;
00188 int i;
00189 int component_count = 0;
00190 char * cname;
00191 NODE * csig;
00192
00193 maplist(t, tsig -> ts_clist, {
00194 switch(t -> kind) {
00195 case DEFCHARSIGS:
00196 s = &(t -> dcs_0);
00197 for (i = 0; i < NVECTORS; i++) {
00198 if (s[i] != 0) {
00199 errmsg0(t, "Can't generate stub for quoted identifier");
00200 break;
00201 }
00202 }
00203 break;
00204 case TSCOMPONENT:
00205 csig = sig_structure(t -> tsc_signature);
00206 if (csig -> kind != FUNCSIGNATURE){
00207 errmsg0(csig, "Can't generate stup for non-function");
00208 break;
00209 }
00210 cname = (char *)getname(t -> tsc_id -> id_str_table_index);
00211 if (!valid_C_id(cname)) {
00212 errmsg1(csig, "Can't generate stub named %s", cname);
00213 break;
00214 }
00215 compile_stub(cname, t -> tsc_signature,
00216 lbl, ar_lbl, component_count++);
00217 break;
00218 }
00219 });
00220 }