00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include <elf.h>
00054 #include <ctype.h>
00055
00056 #define USE_STANDARD_TYPES 1
00057 #include "defs.h"
00058 #include "targ_const.h"
00059 #include "targ_const_private.h"
00060 #include "erglob.h"
00061 #include "errors.h"
00062 #include "config_asm.h"
00063
00064 #ifndef QIKKI_BE
00065 #include "stab.h"
00066 #endif
00068 #define APPEND_TO_DBUF(a,b) a = Targ_Append_To_Dbuf(a,b)
00069
00070
00071
00072 static BOOL
00073 Has_Control_Char (char *str, INT len)
00074 {
00075 INT i;
00076 for (i = 0; i < len; ++i) {
00077 if (iscntrl(str[i]))
00078 return TRUE;
00079 if (str[i] == '"')
00080 return TRUE;
00081 if (str[i] == '\\')
00082 return TRUE;
00083 }
00084 return FALSE;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 void
00105 Targ_Emit_String ( FILE *fl, char *str, INT32 len, INTSC loc )
00106 {
00107 #define MAX_LEN 8
00108 INT ch, i;
00109 INT16 n_on_line = 0;
00110 char dbuf[(1+MAX_LEN)*4], *dptr;
00111 dptr = dbuf;
00112
00113 if (loc != 0)
00114 fprintf(fl, "\t%s offset %1ld\n", ASM_CMNT, loc);
00115
00116
00117 if (len < 80 && str[len-1] == '\0' && ! Has_Control_Char(str,len-1)) {
00118 fprintf(fl, "\tstringz \"%s\"\n", str);
00119 return;
00120 }
00121 for ( i=0; i<len; ++i ) {
00122 ch = str[i];
00123 fprintf ( fl, n_on_line ? ", " : "\t%s\t", AS_BYTE );
00124 fprintf ( fl, "0x%x", ch );
00125 APPEND_TO_DBUF(dptr, ch);
00126 ++n_on_line;
00127 if ( n_on_line == MAX_LEN ) {
00128 *dptr = '\0';
00129 fprintf(fl, "\t%s %s", ASM_CMNT, dbuf);
00130 dptr = dbuf;
00131 fprintf ( fl, "\n" );
00132 n_on_line = 0;
00133 }
00134 }
00135 *dptr = '\0';
00136 fprintf(fl, "\t%s %s", ASM_CMNT, dbuf);
00137 dptr = dbuf;
00138 fprintf(fl, "\n");
00139
00140 #if TARGET_88000 || TARGET_spc00
00141 INT l, line_len, ch, i;
00142
00143 fprintf(fl, "\t%s loc %1d\n", ASM_CMNT, loc);
00144 #define MAX_LEN 60
00145 line_len = -1;
00146 for (i=0; i<len; i++) {
00147 ch = str[i] & 0xff;
00148 if (ch < ' ' || ch > '~' || ch == '\\' || ch == '"')
00149 l = 4;
00150 else
00151 l = 1;
00152 if (line_len > (MAX_LEN-l)) {
00153 fprintf(fl, "\"\n");
00154 line_len = -1;
00155 }
00156 if (line_len < 0) {
00157 fprintf(fl, "\t%s\t\"", AS_STRING );
00158 line_len = 0;
00159 }
00160 if (l == 4)
00161 fprintf(fl, "\\%03o", ch);
00162 else
00163 fprintf(fl, "%c", ch);
00164 line_len += l;
00165 }
00166 Is_True(line_len, ("Expecting non zero line_len"));
00167 if (line_len >= 0)
00168 fprintf(fl, "\"\n");
00169 #endif
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 static void Emit_Repeated_Constant(
00183 FILE *fl,
00184 const char *dir,
00185 INT64 val,
00186 INTSC rc,
00187 INTSC maxc)
00188 {
00189 INTSC this_rc;
00190 do {
00191 INT i;
00192 this_rc = MIN(rc, maxc);
00193 fprintf(fl, "\t%s\t%lld", dir, val);
00194 for (i = 1; i < this_rc; ++i) fprintf(fl, ", %lld", val);
00195 fprintf(fl, "\n");
00196 } while (rc -= this_rc);
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 void
00213 Targ_Emit_Const (FILE *fl,
00214 TCON tc,
00215 BOOL add_null,
00216 INTSC rc,
00217 INTSC loc )
00218 {
00219 Is_True ( rc > 0, ("Targ_Emit_Const: repeat count is %d", rc ) );
00220
00221
00222 fprintf(fl, "\t%s offset %1ld\n", ASM_CMNT, loc);
00223
00224
00225
00226
00227 while (rc) {
00228 switch (TCON_ty(tc)) {
00229 case MTYPE_I1:
00230 case MTYPE_U1:
00231 Emit_Repeated_Constant ( fl, AS_BYTE, TCON_v0(tc) & 0xff, rc, 10 );
00232 rc = 0;
00233 break;
00234
00235 case MTYPE_I2:
00236 case MTYPE_U2:
00237 Emit_Repeated_Constant ( fl,
00238 ((loc % 2) == 0 ? AS_HALF : AS_HALF_UNALIGNED),
00239 TCON_v0(tc) & 0xffff, rc, 8 );
00240 rc = 0;
00241 break;
00242
00243 case MTYPE_I4:
00244 case MTYPE_U4:
00245 Emit_Repeated_Constant ( fl,
00246 ((loc % 4) == 0 ? AS_WORD : AS_WORD_UNALIGNED),
00247 TCON_v0(tc), rc, 4 );
00248 rc = 0;
00249 break;
00250
00251 case MTYPE_I8:
00252 case MTYPE_U8:
00253 Emit_Repeated_Constant ( fl,
00254 ((loc % 8) == 0 ? AS_DWORD : AS_DWORD_UNALIGNED),
00255 TCON_I8(tc), rc, 2 );
00256 rc = 0;
00257 break;
00258
00259 case MTYPE_F4: {
00260 char *p = (char *) & TCON_R4(tc);
00261 fprintf ( fl, "\t%s\t\"", AS_STRING );
00262 for (INT i = 0; i < sizeof(TCON_R4(tc)); i++)
00263 fprintf ( fl, "\\x%02x", *(p+i) );
00264 fprintf(fl, "\"\t%s float %#g\n", ASM_CMNT, TCON_R4(tc) );
00265 --rc;
00266 break;
00267 }
00268
00269 case MTYPE_C4: {
00270 INT i;
00271 char *p = (char *) & TCON_R4(tc);
00272 fprintf ( fl, "\t%s\t\"", AS_STRING );
00273 for (i = 0; i < sizeof(TCON_R4(tc)); i++)
00274 fprintf ( fl, "\\x%02x", *(p+i) );
00275 fprintf(fl, "\"\t%s complex float real part %#g\n", ASM_CMNT, TCON_R4(tc) );
00276
00277 p = (char *) & TCON_IR4(tc);
00278 fprintf ( fl, "\t%s\t\"", AS_STRING );
00279 for (i = 0; i < sizeof(TCON_IR4(tc)); i++)
00280 fprintf ( fl, "\\x%02x", *(p+i) );
00281 fprintf(fl, "\"\t%s complex float imag part %#g\n", ASM_CMNT, TCON_IR4(tc) );
00282 --rc;
00283 break;
00284 }
00285
00286 case MTYPE_F8: {
00287 char *p = (char *) & TCON_R8(tc);
00288 fprintf ( fl, "\t%s\t\"", AS_STRING );
00289 for (INT i = 0; i < sizeof(TCON_R8(tc)); i++)
00290 fprintf ( fl, "\\x%02x", *(p+i) );
00291 fprintf(fl, "\"\t%s double %#g\n", ASM_CMNT, TCON_R8(tc) );
00292 --rc;
00293 break;
00294 }
00295
00296 case MTYPE_C8: {
00297 INT i;
00298 char *p = (char *) & TCON_R8(tc);
00299 fprintf ( fl, "\t%s\t\"", AS_STRING );
00300 for (i = 0; i < sizeof(TCON_R8(tc)); i++)
00301 fprintf ( fl, "\\x%02x", *(p+i) );
00302 fprintf(fl, "\"\t%s complex double real part %#g\n", ASM_CMNT, TCON_R8(tc) );
00303
00304 p = (char *) & TCON_IR8(tc);
00305 fprintf ( fl, "\t%s\t\"", AS_STRING );
00306 for (i = 0; i < sizeof(TCON_IR8(tc)); i++)
00307 fprintf ( fl, "\\x%02x", *(p+i) );
00308 fprintf(fl, "\"\t%s complex double imag part %#g\n", ASM_CMNT, TCON_IR8(tc) );
00309 --rc;
00310 break;
00311 }
00312
00313 case MTYPE_FQ: {
00314 char *p = (char *) & TCON_R16(tc);
00315 fprintf ( fl, "\t%s\t\"", AS_STRING );
00316 for (INT i = 0; i < sizeof(TCON_R16(tc)); i++)
00317 fprintf ( fl, "\\x%02x", *(p+i) );
00318 fprintf(fl, "\"\t%s quad %#lg\n", ASM_CMNT, TCON_R16(tc) );
00319 --rc;
00320 break;
00321 }
00322
00323 case MTYPE_CQ: {
00324 INT i;
00325 char *p = (char *) & TCON_R16(tc);
00326 fprintf ( fl, "\t%s\t\"", AS_STRING );
00327 for (i = 0; i < sizeof(TCON_R16(tc)); i++)
00328 fprintf ( fl, "\\x%02x", *(p+i) );
00329 fprintf(fl, "\"\t%s complex quad real part %#lg\n", ASM_CMNT, TCON_R16(tc) );
00330
00331 p = (char *) & TCON_IR16(tc);
00332 fprintf ( fl, "\t%s\t\"", AS_STRING );
00333 for (i = 0; i < sizeof(TCON_IR16(tc)); i++)
00334 fprintf ( fl, "\\x%02x", *(p+i) );
00335 fprintf(fl, "\"\t%s complex quad imag part %#lg\n", ASM_CMNT, TCON_IR16(tc) );
00336 --rc;
00337 break;
00338 }
00339
00340 case MTYPE_STRING: {
00341 INTSC count;
00342 for (count=0; count<rc; ++count) {
00343 char *p = Index_to_char_array (TCON_cp(tc));
00344 Targ_Emit_String ( fl, p, TCON_len(tc) + (add_null ? 1 : 0), 0 );
00345 }
00346 rc = 0;
00347 break;
00348 }
00349
00350 default:
00351 ErrMsg ( EC_Inv_Mtype, Mtype_Name(TCON_ty(tc)),
00352 "Targ_Emit_Const" );
00353 }
00354 }
00355 }
00356
00357 #if defined(BACK_END) || defined(QIKKI_BE)
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 #include <elf.h>
00368 #include "em_elf.h"
00369
00370 void
00371 Em_Targ_Emit_Const (void *scn,
00372 TCON tc,
00373 BOOL add_null,
00374 INTSC rc)
00375 {
00376 INTSC count;
00377 pSCNINFO section = (pSCNINFO)scn;
00378
00379 Is_True ( rc > 0, ("Em_Targ_Emit_Const: repeat count is %d", rc ) );
00380
00381 switch (TCON_ty(tc)) {
00382 case MTYPE_I1:
00383 case MTYPE_U1:
00384 for (count = 0; count < rc; count++) {
00385 mINT8 value = TCON_v0(tc);
00386 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00387 }
00388 break;
00389
00390 case MTYPE_I2:
00391 case MTYPE_U2:
00392 for (count = 0; count < rc; count++) {
00393 mINT16 value = TCON_v0(tc);
00394 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00395 }
00396 break;
00397
00398 case MTYPE_I4:
00399 case MTYPE_U4:
00400 for (count = 0; count < rc; count++) {
00401 mINT32 value = TCON_v0(tc);
00402 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00403 }
00404 break;
00405
00406 case MTYPE_I8:
00407 case MTYPE_U8:
00408 for (count = 0; count < rc; count++) {
00409 mUINT64 value = TCON_U8(tc);
00410 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00411 }
00412 break;
00413
00414 case MTYPE_F4:
00415 for (count = 0; count < rc; count++) {
00416 float value = TCON_R4(tc);
00417 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00418 }
00419 break;
00420
00421 case MTYPE_C4:
00422 for (count = 0; count < rc; count++) {
00423 float value = TCON_R4(tc);
00424 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00425 value = TCON_IR4(tc);
00426 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00427 }
00428 break;
00429
00430 case MTYPE_F8:
00431 for (count = 0; count < rc; count++) {
00432 double value = TCON_R8(tc);
00433 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00434 }
00435 break;
00436
00437 case MTYPE_C8:
00438 for (count = 0; count < rc; count++) {
00439 double value = TCON_R8(tc);
00440 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00441 value = TCON_IR8(tc);
00442 Em_Add_Bytes_To_Scn (section, (char *) &value, sizeof(value), 1);
00443 }
00444 break;
00445
00446 case MTYPE_FQ:
00447 for (count = 0; count < rc; count++) {
00448 double *pvalue = &(TCON_R8(tc));
00449 Em_Add_Bytes_To_Scn (section, (char *) pvalue, sizeof(double), 1);
00450 Em_Add_Bytes_To_Scn (section, (char *) (pvalue+1), sizeof(double), 1);
00451 }
00452 break;
00453
00454 case MTYPE_CQ:
00455 for (count = 0; count < rc; count++) {
00456 double *pvalue = &(TCON_R8(tc));
00457 Em_Add_Bytes_To_Scn (section, (char *) pvalue, sizeof(double), 1);
00458 Em_Add_Bytes_To_Scn (section, (char *) (pvalue+1), sizeof(double), 1);
00459 pvalue = &(TCON_IR8(tc));
00460 Em_Add_Bytes_To_Scn (section, (char *) pvalue, sizeof(double), 1);
00461 Em_Add_Bytes_To_Scn (section, (char *) (pvalue+1), sizeof(double), 1);
00462 }
00463 break;
00464
00465 case MTYPE_STRING:
00466 for (count = 0; count < rc; count++) {
00467 Em_Add_Bytes_To_Scn (section,
00468 Index_to_char_array (TCON_cp(tc)),
00469 TCON_len(tc) + (add_null ? 1 : 0),
00470 1);
00471 }
00472 break;
00473
00474 default:
00475 Is_True ( FALSE, ( "Targ_Emit_Const can not handle type %s",
00476 Mtype_Name(TCON_ty(tc)) ) );
00477 }
00478 }
00479 #endif
00480
00481 #if !defined(MONGOOSE_BE) && !defined(QIKKI_BE)
00482 void
00483 Targ_Emit_Space( FILE *fl, INT len, INT loc)
00484 {
00485 fprintf(fl, "\t%s %1d\t%s %1d\n", AS_SPACE, len, ASM_CMNT, loc);
00486 }
00487
00488 void
00489 Targ_Emit_Cmt(fl, str)
00490 FILE *fl;
00491 char *str;
00492 {
00493 fprintf(fl, "\t%s %s\n", ASM_CMNT, str);
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void
00505 Targ_Emit_Dim (FILE *fl, TY *ty, INT dim)
00506 {
00507 #if TODO_MONGOOSE
00508 INT32 coff_dim = 1;
00509 ND *tree_lower;
00510 ND *tree_upper;
00511
00512 Is_True(TY_kind(ty) == KIND_ARRAY, ("Non-array in Targ_Emit_Dim"));
00513 Is_True(dim >= 0 && dim < TY_AR_ndims(ty),
00514 ("Illegal dimension %d in Targ_Emit_Dim", dim));
00515
00516 tree_lower = TY_AR_fbnd(ty,dim);
00517 tree_upper = TY_AR_tbnd(ty,dim);
00518 if ( (tree_upper != NULL) && (tree_lower != NULL) ) {
00519 TCON tc_upper, tc_lower;
00520 if ( (Is_Const(tree_upper,&tc_upper) == MTYPE_I4) &&
00521 (Is_Const(tree_lower,&tc_lower) == MTYPE_I4) ) {
00522 INT32 upper_bound = TCON_v0(tc_upper);
00523 INT32 lower_bound = TCON_v0(tc_lower);
00524 coff_dim = upper_bound - lower_bound + 1;
00525 }
00526 }
00527
00528 fprintf ( fl, "%d", coff_dim );
00529 #endif
00530 }
00531 #endif