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