static ir_entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op, const ir_mode *imode, const ir_mode *omode, void *context) { (void)omode; (void)context; const char *name; if (op == op_Div) { name = mode_is_signed(imode) ? "__divdi3" : "__udivdi3"; } else if (op == op_Mod) { name = mode_is_signed(imode) ? "__moddi3" : "__umoddi3"; } else { panic("ia32: Unexpected lowering of 64bit op %s", get_op_name(op)); } return create_compilerlib_entity(new_id_from_str(name), method); }
void output_function_indent(NODE *node, int indent) { int i; if (node == NULL) { return; } for (i = 0; i < indent * 2; i++) { printf(" "); } printf("%s\n", get_op_name(node->op)); for (i = 0; i < node->numargs; i++) { output_function_indent(node->arg[i], indent + 1); } }
static void dump_status( StatWrapper &stat, const char *label ) { int opint; for( opint = StatWrapper::STATOP_MIN; opint <= StatWrapper::STATOP_MAX; opint++ ) { StatWrapper::StatOpType opno = (StatWrapper::StatOpType) opint; const char *fn = stat.GetStatFn( opno ); if ( NULL == fn ) { fn = "<NULL>"; } const char *name = get_op_name( opno ); StatStructType buf; int err = 0; bool valid = false; bool getbuf = false; int rc = stat.GetRc( opno ); if ( rc ) { err = stat.GetErrno( opno ); } valid = stat.IsBufValid( opno ); if( valid ) { getbuf = stat.GetBuf( buf, opno ); } printf( " %s %s: fn=%s; rc=%d errno=%d valid=%s getbuf=%s\n", label, name, fn, rc, err, valid ? "true":"false", getbuf ? "true":"false" ); if ( valid ) { printf( " buf: dev=%d ino=%u mode=%03o nlink=%d ids=%d/%d\n" " size=%lld a/m/ctime=%d/%d/%d\n", (int)buf.st_dev, (unsigned)buf.st_ino, (unsigned)buf.st_mode, (int)buf.st_nlink, (int)buf.st_uid, (int)buf.st_gid, (long long)buf.st_size, (int)buf.st_atime, (int)buf.st_mtime, (int)buf.st_ctime ); } } }
int main( int argc, const char *argv[] ) { int fd; const char *path; StatWrapper *wrapper = NULL; const char *usage = "test [-h|--help] <file> [operations]"; if ( argc < 2 ) { fprintf( stderr, "no file specified\n" ); fprintf( stderr, "%s\n", usage ); exit( 1 ); } path = argv[1]; if ( *path == '-' ) { fprintf( stderr, "no file specified\n" ); fprintf( stderr, "%s\n", usage ); Help( argv[0] ); exit( 1 ); } fd = safe_open_wrapper_follow( path, O_RDONLY ); printf( "path set to '%s', fd to %d\n", path, fd ); int argno; int skip = 0; for( argno = 2; argno < argc; argno++ ) { if ( skip ) { skip--; continue; } const char *arg = argv[argno]; const char *arg1 = NULL; const char *arg2 = NULL; const char *arg3 = NULL; if ( arg && (argc > (argno+1)) && (*argv[argno+1] != '-') ) { arg1 = argv[argno+1]; } if ( arg1 && (argc > (argno+2)) && (*argv[argno+2] != '-') ) { arg2 = argv[argno+2]; } if ( arg2 && (argc > (argno+3)) && (*argv[argno+3] != '-') ) { arg3 = argv[argno+3]; } if ( (!strcmp( arg, "--help" )) || (!strcmp( arg, "-h")) ) { Help( argv[0] ); exit( 0 ); } else if ( (!strcmp( arg, "--path" )) || (!strcmp( arg, "-p")) ) { if ( !arg1 ) { fprintf( stderr, "--path usage: --path <path>\n" ); exit( 1 ); } path = arg1; fd = safe_open_wrapper_follow( path, O_RDONLY ); skip = 1; printf( "path set to '%s', fd to %d\n", path, fd ); } else if ( (!strcmp( arg, "--create" )) || (!strcmp( arg, "-c")) ) { if ( !arg1 || !arg2 ) { fprintf( stderr, "--create usage: --create <op> <which>\n" ); exit( 1 ); } skip = 2; const StatOp *op = get_op( arg1 ); const StatOp *which = get_op( arg1 ); const char *n = ""; bool auto_stat = false; // Create the object switch ( op->type ) { case StatWrapper::STATOP_STAT: case StatWrapper::STATOP_LSTAT: case StatWrapper::STATOP_BOTH: n = "StatWrapper(path,which)"; auto_stat = ( (which->type==StatWrapper::STATOP_STAT) || (which->type==StatWrapper::STATOP_LSTAT) || (which->type==StatWrapper::STATOP_BOTH) || (which->type==StatWrapper::STATOP_ALL) ); wrapper = new StatWrapper( path, which->type ); break; case StatWrapper::STATOP_FSTAT: n = "StatWrapper(fd,which)"; wrapper = new StatWrapper( fd, which->type ); auto_stat = ( (which->type==StatWrapper::STATOP_FSTAT) || (which->type==StatWrapper::STATOP_ALL) ); break; case StatWrapper::STATOP_NONE: n = "StatWrapper(void)"; wrapper = new StatWrapper; break; case StatWrapper::STATOP_ALL: case StatWrapper::STATOP_LAST: default: fprintf( stderr, "%s (%d) doesn't make sense for create\n", op->str, op->type ); exit( 1 ); break; } if ( !wrapper ) { fprintf( stderr, "Failed to create StatWrapper (%s) object!\n", n ); exit( 1 ); } printf( "Created StatWrapper object via %s\n", n ); printf( "Stat Functions:\n" ); int opint; for( opint = (int)StatWrapper::STATOP_MIN; opint <= (int)StatWrapper::STATOP_MAX; opint++ ) { StatWrapper::StatOpType opno = (StatWrapper::StatOpType) opint; const char *fn = wrapper->GetStatFn( opno ); if ( NULL == fn ) { fn = "<NULL>"; } const char *name = get_op_name( opno ); printf( " %s = %s\n", name, fn ); } if ( auto_stat ) { dump_status( *wrapper, "Stat results" ); } } else if ( !strcmp( arg, "--set" ) ) { skip = 1; if ( !arg1 ) { fprintf( stderr, "--set usage: --set <op>\n" ); exit( 1 ); } const StatOp *op = get_op( arg1 ); if ( !wrapper ) { fprintf( stderr, "--set: no wrapper object!\n" ); exit( 1 ); } // Set operations bool rc1 = false, rc2 = false; const char *n1 = "", *n2 = ""; switch ( op->type ) { case StatWrapper::STATOP_STAT: case StatWrapper::STATOP_LSTAT: case StatWrapper::STATOP_BOTH: n1 = "SetPath"; rc1 = wrapper->SetPath( path ); break; case StatWrapper::STATOP_FSTAT: n1 = "SetFd"; rc1 = wrapper->SetFD( fd ); break; case StatWrapper::STATOP_NONE: break; case StatWrapper::STATOP_ALL: n1 = "SetPath"; rc1 = wrapper->SetPath( path ); n2 = "SetFD"; rc2 = wrapper->SetFD( fd ); break; case StatWrapper::STATOP_LAST: default: fprintf( stderr, "%s (%d) doesn't make sense for set\n", op->str, op->type ); exit( 1 ); break; } if ( rc1 || rc2 ) { printf( "set via %s [%s/%s] OK\n", op->str, n1, n2 ); } else { fprintf( stderr, "set via %s [%s/%s] FAILED\n", op->str, n1, n2 ); exit( 1 ); } } else if ( (!strcmp( arg, "--stat" )) || (!strcmp( arg, "-s")) ) { if ( !arg2 ) { fprintf( stderr, "--stat usage: --stat <op> <which> [f[orce]|[no]]\n"); exit( 1 ); } const StatOp *op = get_op( arg1 ); const StatOp *which = get_op( arg2 ); bool force = true; bool force_set; if ( arg3 ) { skip = 3; force = ( (!strcasecmp(arg3,"f")) || (!strcasecmp(arg3,"force")) ); } else { skip = 2; force_set = false; } if ( !wrapper ) { fprintf( stderr, "--stat: no wrapper object!\n" ); exit( 1 ); } // Stat operations int rc1 = 0, rc2 = 0; bool op2 = false; char *n1 = "", *n2 = ""; switch ( op->type ) { case StatWrapper::STATOP_NONE: case StatWrapper::STATOP_LAST: if ( force_set ) { n1 = "Stat(which,force)"; rc1 = wrapper->Stat( which->type, force ); } else { n1 = "Stat(which)"; rc1 = wrapper->Stat( which->type ); } break; case StatWrapper::STATOP_STAT: case StatWrapper::STATOP_LSTAT: case StatWrapper::STATOP_BOTH: if ( force_set ) { n1 = "Stat(path,which,force)"; rc1 = wrapper->Stat( path, which->type, force ); } else { n1 = "Stat(path,which)"; rc1 = wrapper->Stat( path, which->type ); } break; case StatWrapper::STATOP_FSTAT: if ( force_set ) { n1 = "Stat(fd,force)"; rc1 = wrapper->Stat( fd, which->type, force ); } else { n1 = "Stat(fd)"; rc1 = wrapper->Stat( fd ); } break; case StatWrapper::STATOP_ALL: if ( force_set ) { n1 = "Stat(path,which,force)"; rc1 = wrapper->Stat( path, which->type, force ); n2 = "Stat(fd,force)"; rc2 = wrapper->Stat( fd, force ); } else { n1 = "Stat(path,which)"; rc1 = wrapper->Stat( path, which->type ); n2 = "Stat(fd)"; rc2 = wrapper->Stat( fd ); } op2 = true; break; default: fprintf( stderr, "%s (%d) doesn't make sense for create\n", op->str, op->type ); } printf( "%s %s (%d)\n", n1, rc1 ? "Failed":"OK", rc1 ); if ( op2 ) { printf( "%s %s (%d)\n", n2, rc2 ? "Failed":"OK", rc2 ); } dump_status( *wrapper, "Stat results" ); } else if ( (!strcmp( arg, "--retry" )) || (!strcmp( arg, "-r")) ) { if ( !wrapper ) { fprintf( stderr, "--retry: no wrapper object!\n" ); exit( 1 ); } int rc = wrapper->Retry( ); printf( "Retry %s: %d\n", rc ? "Failed":"OK", rc ); dump_status( *wrapper, "Retry results" ); } else if ( (!strcmp( arg, "--query" )) || (!strcmp( arg, "-q")) ) { if ( !wrapper ) { fprintf( stderr, "--query: no wrapper object!\n" ); exit( 1 ); } dump_status( *wrapper, "Query results" ); } else { fprintf( stderr, "Unknown command %s\n", arg ); } } return 0; }
void output_node(NODE *node, int break_label, int continue_label) { NODE *n; int top, cont, out, bottom, not, tmp1, imm, state; int stack_size; static int last_line = -1; if (node == NULL) { return; } // In case we call yyerror(). yylineno = node->line; if (node->line != last_line && node->op != ';' && node->op != FOR) { last_line = node->line; /* fprintf(outf, "%d, %s\n", node->op, get_op_name(node->op)); */ output_line(node->line); } switch (node->op) { case NUMBER: output_code("LD", "HL, %d", node->data.value); break; case STRING: output_code("LD", "HL, %s", node->data.address); break; case IDENT: if (node->data.var->scope == SCOPE_GLOBAL) { if (node->lhs) { output_code("LD", "IX, _%s", node->data.var->name); } else if (node->data.var->decl->decl_type == DECL_ARRAY) { output_code("LD", "HL, _%s", node->data.var->name); } else { output_code("LD", "HL, (_%s)", node->data.var->name); } } else { if (node->lhs) { output_code("PUSH", "IY"); output_code("POP", "IX"); output_code("LD", "BC, %d", node->data.var->offset); output_code("ADD", "IX, BC"); } else if (node->data.var->decl->decl_type == DECL_ARRAY) { output_code("LD", "BC, %d", node->data.var->offset); output_code("PUSH", "IY"); output_code("POP", "HL"); output_code("ADD", "HL, BC"); } else { output_code("LD", "L, (IY + %d)", node->data.var->offset); output_code("LD", "H, (IY + %d)", node->data.var->offset + 1); } } break; case '(': /* limited function call support */ stack_size = output_parameters(node->arg[1], break_label, continue_label); output_code("CALL", "_%s", node->arg[0]->data.var->name); while (stack_size-- > 0) { output_code("INC", "SP"); } break; case INCR: output_node(node->arg[0], break_label, continue_label); /* Address is in IX */ if (node->data.detail == -1) { /* Preincrement */ output_code("LD", "L, (IX + 0)"); output_code("LD", "H, (IX + 1)"); output_code("INC", "HL"); output_code("LD", "(IX + 0), L"); output_code("LD", "(IX + 1), H"); } else { /* Postincrement */ output_code("LD", "L, (IX + 0)"); output_code("LD", "H, (IX + 1)"); output_code("LD", "E, L"); output_code("LD", "D, H"); output_code("INC", "DE"); output_code("LD", "(IX + 0), E"); output_code("LD", "(IX + 1), D"); } break; case DECR: output_node(node->arg[0], break_label, continue_label); /* Address is in IX */ if (node->data.detail == -1) { /* Predecrement */ output_code("LD", "L, (IX + 0)"); output_code("LD", "H, (IX + 1)"); output_code("DEC", "HL"); output_code("LD", "(IX + 0), L"); output_code("LD", "(IX + 1), H"); } else { /* Postdecrement */ output_code("LD", "L, (IX + 0)"); output_code("LD", "H, (IX + 1)"); output_code("LD", "E, L"); output_code("LD", "D, H"); output_code("DEC", "DE"); output_code("LD", "(IX + 0), E"); output_code("LD", "(IX + 1), D"); } break; case CAST: output_node(node->arg[0], break_label, continue_label); /* * Use get_decl_size() to do the right thing here. Not * necessary right now. */ break; case SIZEOF: output_code("LD", "HL, %d", get_decl_size(node->arg[0]->decl)); break; case '*': if (node->numargs == 1) { // Pointer dereference. output_node(node->arg[0], break_label, continue_label); output_code("PUSH", "HL"); output_code("POP", "IX"); if (!node->lhs) { // Actually dereference it. output_code("LD", "H, (IX + 1)"); output_code("LD", "L, (IX)"); } } else { // Multiplication. if (node->arg[0]->op == NUMBER || node->arg[1]->op == NUMBER) { if (node->arg[0]->op == NUMBER) { n = node->arg[0]; node->arg[0] = node->arg[1]; node->arg[1] = n; } output_node(node->arg[0], break_label, continue_label); imm = node->arg[1]->data.value; if (imm < 0) { imm = -imm; output_code("LD", "A, 255"); output_code("XOR", "H"); output_code("XOR", "L"); output_code("INC", "HL"); } if (imm == 0) { output_code("LD", "HL, 0"); } else if ((imm & (imm - 1)) == 0) { /* Power of two */ while (imm != 1) { output_code("ADD", "HL, HL"); imm >>= 1; } } else { if ((imm & 1) != 0) { output_code("LD", "D, H"); output_code("LD", "E, L"); imm &= ~1; } else { output_code("LD", "DE, 0"); } state = 0; /* state = 1 when HL contains the output */ while (imm != 1) { if ((imm & 1) != 0) { if (!state) { output_code("EX", "DE, HL"); } state = 1; output_code("ADD", "HL, DE"); } if (state) { output_code("EX", "DE, HL"); state = 0; } output_code("ADD", "HL, HL"); imm >>= 1; } /* Doesn't matter what "state" is */ output_code("ADD", "HL, DE"); } } else { output_comment("Unsupported operands: %s.", get_op_name(node->op)); unsupported++; } }