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