1479 generate_peepreplace( fp, _globalNames, pmatch, pconstraint, preplace, max_position );
1480
1481 // End of scope for this peephole's constraints
1482 fprintf(fp, " }\n");
1483 // Closing brace '}' to make each peephole rule individually selectable
1484 fprintf(fp, " } // end of peephole rule #%d\n", peephole_number);
1485 fprintf(fp, "\n");
1486 }
1487
1488 fprintf(fp, " return NULL; // No peephole rules matched\n");
1489 fprintf(fp, "}\n");
1490 fprintf(fp, "\n");
1491 }
1492
1493 // Define the Expand method for an instruction node
1494 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
1495 unsigned cnt = 0; // Count nodes we have expand into
1496 unsigned i;
1497
1498 // Generate Expand function header
1499 fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident);
1500 fprintf(fp,"Compile* C = Compile::current();\n");
1501 // Generate expand code
1502 if( node->expands() ) {
1503 const char *opid;
1504 int new_pos, exp_pos;
1505 const char *new_id = NULL;
1506 const Form *frm = NULL;
1507 InstructForm *new_inst = NULL;
1508 OperandForm *new_oper = NULL;
1509 unsigned numo = node->num_opnds() +
1510 node->_exprule->_newopers.count();
1511
1512 // If necessary, generate any operands created in expand rule
1513 if (node->_exprule->_newopers.count()) {
1514 for(node->_exprule->_newopers.reset();
1515 (new_id = node->_exprule->_newopers.iter()) != NULL; cnt++) {
1516 frm = node->_localNames[new_id];
1517 assert(frm, "Invalid entry in new operands list of expand rule");
1518 new_oper = frm->is_operand();
1519 char *tmp = (char *)node->_exprule->_newopconst[new_id];
1520 if (tmp == NULL) {
1801 declared_kill = true;
1802 }
1803
1804 assert( op, "Support additional KILLS for base operands");
1805 const char *regmask = reg_mask(*op);
1806 const char *ideal_type = op->ideal_type(_globalNames, _register);
1807
1808 if (!op->is_bound_register()) {
1809 syntax_err(node->_linenum, "In %s only bound registers can be killed: %s %s\n",
1810 node->_ident, comp->_type, comp->_name);
1811 }
1812
1813 fprintf(fp," kill = ");
1814 fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
1815 machNode, proj_no++, regmask, ideal_type);
1816 fprintf(fp," proj_list.push(kill);\n");
1817 }
1818 }
1819 }
1820
1821 fprintf(fp,"\n");
1822 if( node->expands() ) {
1823 fprintf(fp," return result;\n");
1824 } else {
1825 fprintf(fp," return this;\n");
1826 }
1827 fprintf(fp,"}\n");
1828 fprintf(fp,"\n");
1829 }
1830
1831
1832 //------------------------------Emit Routines----------------------------------
1833 // Special classes and routines for defining node emit routines which output
1834 // target specific instruction object encodings.
1835 // Define the ___Node::emit() routine
1836 //
1837 // (1) void ___Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1838 // (2) // ... encoding defined by user
1839 // (3)
1840 // (4) }
1907 _doing_emit_hi = false;
1908 _doing_emit_lo = false;
1909 _may_reloc = false;
1910 _must_reloc = false;
1911 _reloc_form = RELOC_NONE;
1912 _reloc_type = AdlcVMDeps::none_reloc_type();
1913 _strings_to_emit.clear();
1914 }
1915
1916 // Track necessary state when identifying a replacement variable
1917 void update_state(const char *rep_var) {
1918 // A replacement variable or one of its subfields
1919 // Obtain replacement variable from list
1920 if ( (*rep_var) != '$' ) {
1921 // A replacement variable, '$' prefix
1922 // check_rep_var( rep_var );
1923 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
1924 // No state needed.
1925 assert( _opclass == NULL,
1926 "'primary', 'secondary' and 'tertiary' don't follow operand.");
1927 } else {
1928 // Lookup its position in parameter list
1929 int param_no = _encoding.rep_var_index(rep_var);
1930 if ( param_no == -1 ) {
1931 _AD.syntax_err( _encoding._linenum,
1932 "Replacement variable %s not found in enc_class %s.\n",
1933 rep_var, _encoding._name);
1934 }
1935
1936 // Lookup the corresponding ins_encode parameter
1937 const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
1938 if (inst_rep_var == NULL) {
1939 _AD.syntax_err( _ins_encode._linenum,
1940 "Parameter %s not passed to enc_class %s from instruct %s.\n",
1941 rep_var, _encoding._name, _inst._ident);
1942 }
1943
1944 // Check if instruction's actual parameter is a local name in the instruction
1945 const Form *local = _inst._localNames[inst_rep_var];
1946 OpClassForm *opc = (local != NULL) ? local->is_opclass() : NULL;
1947 // Note: assert removed to allow constant and symbolic parameters
2363 fprintf(_fp,"->method()");
2364 }
2365 else {
2366 printf("emit_field: %s\n",rep_var);
2367 assert( false, "UnImplemented()");
2368 }
2369 }
2370
2371
2372 void emit_rep_var(const char *rep_var) {
2373 _processing_noninput = false;
2374 // A replacement variable, originally '$'
2375 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2376 if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
2377 // Missing opcode
2378 _AD.syntax_err( _inst._linenum,
2379 "Missing $%s opcode definition in %s, used by encoding %s\n",
2380 rep_var, _inst._ident, _encoding._name);
2381 }
2382 }
2383 else {
2384 // Lookup its position in parameter list
2385 int param_no = _encoding.rep_var_index(rep_var);
2386 if ( param_no == -1 ) {
2387 _AD.syntax_err( _encoding._linenum,
2388 "Replacement variable %s not found in enc_class %s.\n",
2389 rep_var, _encoding._name);
2390 }
2391 // Lookup the corresponding ins_encode parameter
2392 const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
2393
2394 // Check if instruction's actual parameter is a local name in the instruction
2395 const Form *local = _inst._localNames[inst_rep_var];
2396 OpClassForm *opc = (local != NULL) ? local->is_opclass() : NULL;
2397 // Note: assert removed to allow constant and symbolic parameters
2398 // assert( opc, "replacement variable was not found in local names");
2399 // Lookup the index position iff the replacement variable is a localName
2400 int idx = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
2401 if( idx != -1 ) {
2402 if (_inst.is_noninput_operand(idx)) {
2448 }; // end class DefineEmitState
2449
2450
2451 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
2452
2453 //(1)
2454 // Output instruction's emit prototype
2455 fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
2456 inst._ident);
2457
2458 fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
2459
2460 //(2)
2461 // Print the size
2462 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2463
2464 // (3) and (4)
2465 fprintf(fp,"}\n");
2466 }
2467
2468 void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
2469 InsEncode *ins_encode = inst._insencode;
2470
2471 // (1)
2472 // Output instruction's emit prototype
2473 fprintf(fp,"void %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
2474 inst._ident);
2475
2476 // If user did not define an encode section,
2477 // provide stub that does not generate any machine code.
2478 if( (_encode == NULL) || (ins_encode == NULL) ) {
2479 fprintf(fp, " // User did not define an encode section.\n");
2480 fprintf(fp,"}\n");
2481 return;
2482 }
2483
2484 // Save current instruction's starting address (helps with relocation).
2485 fprintf(fp, " cbuf.set_insts_mark();\n");
2486
2487 // // // idx0 is only needed for syntactic purposes and only by "storeSSI"
2488 // fprintf( fp, " unsigned idx0 = 0;\n");
2489
2490 // Output each operand's offset into the array of registers.
2491 inst.index_temps( fp, _globalNames );
2492
2493 // Output this instruction's encodings
2494 const char *ec_name;
2495 bool user_defined = false;
2496 ins_encode->reset();
2497 while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) {
2498 fprintf(fp, " {");
2499 // Output user-defined encoding
2500 user_defined = true;
2501
2502 const char *ec_code = NULL;
2503 const char *ec_rep_var = NULL;
2504 EncClass *encoding = _encode->encClass(ec_name);
2505 if (encoding == NULL) {
2506 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2507 abort();
2508 }
2509
2510 if (ins_encode->current_encoding_num_args() != encoding->num_args()) {
2511 globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2512 inst._ident, ins_encode->current_encoding_num_args(),
2513 ec_name, encoding->num_args());
2514 }
2515
2516 DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst );
2517 encoding->_code.reset();
2518 encoding->_rep_vars.reset();
2519 // Process list of user-defined strings,
2520 // and occurrences of replacement variables.
2521 // Replacement Vars are pushed into a list and then output
2522 while ( (ec_code = encoding->_code.iter()) != NULL ) {
2523 if ( ! encoding->_code.is_signal( ec_code ) ) {
2524 // Emit pending code
2525 pending.emit();
2526 pending.clear();
2527 // Emit this code section
2528 fprintf(fp,"%s", ec_code);
2529 } else {
2530 // A replacement variable or one of its subfields
2531 // Obtain replacement variable from list
2532 ec_rep_var = encoding->_rep_vars.iter();
2533 pending.add_rep_var(ec_rep_var);
2534 }
2535 }
2536 // Emit pending code
2537 pending.emit();
2538 pending.clear();
2539 fprintf(fp, "}\n");
2540 } // end while instruction's encodings
2541
2542 // Check if user stated which encoding to user
2543 if ( user_defined == false ) {
2544 fprintf(fp, " // User did not define which encode class to use.\n");
2545 }
2546
2547 // (3) and (4)
2548 fprintf(fp,"}\n");
2549 }
2550
2551 // ---------------------------------------------------------------------------
2552 //--------Utilities to build MachOper and MachNode derived Classes------------
2553 // ---------------------------------------------------------------------------
2554
2555 //------------------------------Utilities to build Operand Classes------------
2556 static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
2557 uint num_edges = oper.num_edges(globals);
2558 if( num_edges != 0 ) {
2559 // Method header
2560 fprintf(fp, "const RegMask *%sOper::in_RegMask(int index) const {\n",
2561 oper._ident);
2562
2563 // Assert that the index is in range.
2564 fprintf(fp, " assert(0 <= index && index < %d, \"index out of range\");\n",
2565 num_edges);
2566
2567 // Figure out if all RegMasks are the same.
2568 const char* first_reg_class = oper.in_reg_class(0, globals);
2935 // Output the definitions for out_RegMask() // & kill_RegMask()
2936 _instructions.reset();
2937 InstructForm *instr;
2938 MachNodeForm *machnode;
2939 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
2940 // Ensure this is a machine-world instruction
2941 if ( instr->ideal_only() ) continue;
2942
2943 defineOut_RegMask(_CPP_MISC_file._fp, instr->_ident, reg_mask(*instr));
2944 }
2945
2946 bool used = false;
2947 // Output the definitions for expand rules & peephole rules
2948 _instructions.reset();
2949 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
2950 // Ensure this is a machine-world instruction
2951 if ( instr->ideal_only() ) continue;
2952 // If there are multiple defs/kills, or an explicit expand rule, build rule
2953 if( instr->expands() || instr->needs_projections() ||
2954 instr->has_temps() ||
2955 instr->_matrule != NULL &&
2956 instr->num_opnds() != instr->num_unique_opnds() )
2957 defineExpand(_CPP_EXPAND_file._fp, instr);
2958 // If there is an explicit peephole rule, build it
2959 if ( instr->peepholes() )
2960 definePeephole(_CPP_PEEPHOLE_file._fp, instr);
2961
2962 // Output code to convert to the cisc version, if applicable
2963 used |= instr->define_cisc_version(*this, fp);
2964
2965 // Output code to convert to the short branch version, if applicable
2966 used |= instr->define_short_branch_methods(*this, fp);
2967 }
2968
2969 // Construct the method called by cisc_version() to copy inputs and operands.
2970 define_fill_new_machnode(used, fp);
2971
2972 // Output the definitions for labels
2973 _instructions.reset();
2974 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
3015 fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident);
3016 fprintf(fp, " return %d;\n", reloc_size );
3017 fprintf(fp,"}\n");
3018 fprintf(fp,"\n");
3019 }
3020 }
3021 fprintf(fp,"\n");
3022
3023 // Output the definitions for code generation
3024 //
3025 // address ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
3026 // // ... encoding defined by user
3027 // return ptr;
3028 // }
3029 //
3030 _instructions.reset();
3031 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3032 // Ensure this is a machine-world instruction
3033 if ( instr->ideal_only() ) continue;
3034
3035 if (instr->_insencode) defineEmit(fp, *instr);
3036 if (instr->_size) defineSize(fp, *instr);
3037
3038 // side-call to generate output that used to be in the header file:
3039 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
3040 gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
3041 }
3042
3043 // Output the definitions for alias analysis
3044 _instructions.reset();
3045 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3046 // Ensure this is a machine-world instruction
3047 if ( instr->ideal_only() ) continue;
3048
3049 // Analyze machine instructions that either USE or DEF memory.
3050 int memory_operand = instr->memory_operand(_globalNames);
3051 // Some guys kill all of memory
3052 if ( instr->is_wide_memory_kill(_globalNames) ) {
3053 memory_operand = InstructForm::MANY_MEMORY_OPERANDS;
3054 }
3055
3056 if ( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
|
1479 generate_peepreplace( fp, _globalNames, pmatch, pconstraint, preplace, max_position );
1480
1481 // End of scope for this peephole's constraints
1482 fprintf(fp, " }\n");
1483 // Closing brace '}' to make each peephole rule individually selectable
1484 fprintf(fp, " } // end of peephole rule #%d\n", peephole_number);
1485 fprintf(fp, "\n");
1486 }
1487
1488 fprintf(fp, " return NULL; // No peephole rules matched\n");
1489 fprintf(fp, "}\n");
1490 fprintf(fp, "\n");
1491 }
1492
1493 // Define the Expand method for an instruction node
1494 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
1495 unsigned cnt = 0; // Count nodes we have expand into
1496 unsigned i;
1497
1498 // Generate Expand function header
1499 fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
1500 fprintf(fp, " Compile* C = Compile::current();\n");
1501 // Generate expand code
1502 if( node->expands() ) {
1503 const char *opid;
1504 int new_pos, exp_pos;
1505 const char *new_id = NULL;
1506 const Form *frm = NULL;
1507 InstructForm *new_inst = NULL;
1508 OperandForm *new_oper = NULL;
1509 unsigned numo = node->num_opnds() +
1510 node->_exprule->_newopers.count();
1511
1512 // If necessary, generate any operands created in expand rule
1513 if (node->_exprule->_newopers.count()) {
1514 for(node->_exprule->_newopers.reset();
1515 (new_id = node->_exprule->_newopers.iter()) != NULL; cnt++) {
1516 frm = node->_localNames[new_id];
1517 assert(frm, "Invalid entry in new operands list of expand rule");
1518 new_oper = frm->is_operand();
1519 char *tmp = (char *)node->_exprule->_newopconst[new_id];
1520 if (tmp == NULL) {
1801 declared_kill = true;
1802 }
1803
1804 assert( op, "Support additional KILLS for base operands");
1805 const char *regmask = reg_mask(*op);
1806 const char *ideal_type = op->ideal_type(_globalNames, _register);
1807
1808 if (!op->is_bound_register()) {
1809 syntax_err(node->_linenum, "In %s only bound registers can be killed: %s %s\n",
1810 node->_ident, comp->_type, comp->_name);
1811 }
1812
1813 fprintf(fp," kill = ");
1814 fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
1815 machNode, proj_no++, regmask, ideal_type);
1816 fprintf(fp," proj_list.push(kill);\n");
1817 }
1818 }
1819 }
1820
1821 // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
1822 // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
1823 if (node->is_mach_constant()) {
1824 fprintf(fp," add_req(C->mach_constant_base_node());\n");
1825 }
1826
1827 fprintf(fp,"\n");
1828 if( node->expands() ) {
1829 fprintf(fp," return result;\n");
1830 } else {
1831 fprintf(fp," return this;\n");
1832 }
1833 fprintf(fp,"}\n");
1834 fprintf(fp,"\n");
1835 }
1836
1837
1838 //------------------------------Emit Routines----------------------------------
1839 // Special classes and routines for defining node emit routines which output
1840 // target specific instruction object encodings.
1841 // Define the ___Node::emit() routine
1842 //
1843 // (1) void ___Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1844 // (2) // ... encoding defined by user
1845 // (3)
1846 // (4) }
1913 _doing_emit_hi = false;
1914 _doing_emit_lo = false;
1915 _may_reloc = false;
1916 _must_reloc = false;
1917 _reloc_form = RELOC_NONE;
1918 _reloc_type = AdlcVMDeps::none_reloc_type();
1919 _strings_to_emit.clear();
1920 }
1921
1922 // Track necessary state when identifying a replacement variable
1923 void update_state(const char *rep_var) {
1924 // A replacement variable or one of its subfields
1925 // Obtain replacement variable from list
1926 if ( (*rep_var) != '$' ) {
1927 // A replacement variable, '$' prefix
1928 // check_rep_var( rep_var );
1929 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
1930 // No state needed.
1931 assert( _opclass == NULL,
1932 "'primary', 'secondary' and 'tertiary' don't follow operand.");
1933 }
1934 else if ((strcmp(rep_var, "constanttablebase") == 0) ||
1935 (strcmp(rep_var, "constantoffset") == 0) ||
1936 (strcmp(rep_var, "constantaddress") == 0)) {
1937 if (!_inst.is_mach_constant()) {
1938 _AD.syntax_err(_encoding._linenum,
1939 "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
1940 rep_var, _encoding._name);
1941 }
1942 }
1943 else {
1944 // Lookup its position in parameter list
1945 int param_no = _encoding.rep_var_index(rep_var);
1946 if ( param_no == -1 ) {
1947 _AD.syntax_err( _encoding._linenum,
1948 "Replacement variable %s not found in enc_class %s.\n",
1949 rep_var, _encoding._name);
1950 }
1951
1952 // Lookup the corresponding ins_encode parameter
1953 const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
1954 if (inst_rep_var == NULL) {
1955 _AD.syntax_err( _ins_encode._linenum,
1956 "Parameter %s not passed to enc_class %s from instruct %s.\n",
1957 rep_var, _encoding._name, _inst._ident);
1958 }
1959
1960 // Check if instruction's actual parameter is a local name in the instruction
1961 const Form *local = _inst._localNames[inst_rep_var];
1962 OpClassForm *opc = (local != NULL) ? local->is_opclass() : NULL;
1963 // Note: assert removed to allow constant and symbolic parameters
2379 fprintf(_fp,"->method()");
2380 }
2381 else {
2382 printf("emit_field: %s\n",rep_var);
2383 assert( false, "UnImplemented()");
2384 }
2385 }
2386
2387
2388 void emit_rep_var(const char *rep_var) {
2389 _processing_noninput = false;
2390 // A replacement variable, originally '$'
2391 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2392 if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
2393 // Missing opcode
2394 _AD.syntax_err( _inst._linenum,
2395 "Missing $%s opcode definition in %s, used by encoding %s\n",
2396 rep_var, _inst._ident, _encoding._name);
2397 }
2398 }
2399 else if (strcmp(rep_var, "constanttablebase") == 0) {
2400 fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
2401 }
2402 else if (strcmp(rep_var, "constantoffset") == 0) {
2403 fprintf(_fp, "constant_offset()");
2404 }
2405 else if (strcmp(rep_var, "constantaddress") == 0) {
2406 fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
2407 }
2408 else {
2409 // Lookup its position in parameter list
2410 int param_no = _encoding.rep_var_index(rep_var);
2411 if ( param_no == -1 ) {
2412 _AD.syntax_err( _encoding._linenum,
2413 "Replacement variable %s not found in enc_class %s.\n",
2414 rep_var, _encoding._name);
2415 }
2416 // Lookup the corresponding ins_encode parameter
2417 const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
2418
2419 // Check if instruction's actual parameter is a local name in the instruction
2420 const Form *local = _inst._localNames[inst_rep_var];
2421 OpClassForm *opc = (local != NULL) ? local->is_opclass() : NULL;
2422 // Note: assert removed to allow constant and symbolic parameters
2423 // assert( opc, "replacement variable was not found in local names");
2424 // Lookup the index position iff the replacement variable is a localName
2425 int idx = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
2426 if( idx != -1 ) {
2427 if (_inst.is_noninput_operand(idx)) {
2473 }; // end class DefineEmitState
2474
2475
2476 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
2477
2478 //(1)
2479 // Output instruction's emit prototype
2480 fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
2481 inst._ident);
2482
2483 fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
2484
2485 //(2)
2486 // Print the size
2487 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2488
2489 // (3) and (4)
2490 fprintf(fp,"}\n");
2491 }
2492
2493 // defineEmit -----------------------------------------------------------------
2494 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
2495 InsEncode* encode = inst._insencode;
2496
2497 // (1)
2498 // Output instruction's emit prototype
2499 fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);
2500
2501 // If user did not define an encode section,
2502 // provide stub that does not generate any machine code.
2503 if( (_encode == NULL) || (encode == NULL) ) {
2504 fprintf(fp, " // User did not define an encode section.\n");
2505 fprintf(fp, "}\n");
2506 return;
2507 }
2508
2509 // Save current instruction's starting address (helps with relocation).
2510 fprintf(fp, " cbuf.set_insts_mark();\n");
2511
2512 // For MachConstantNodes which are ideal jump nodes, fill the jump table.
2513 if (inst.is_mach_constant() && inst.is_ideal_jump()) {
2514 fprintf(fp, " fill_jump_table_in_constant_table(cbuf, _index2label);\n");
2515 }
2516
2517 // Output each operand's offset into the array of registers.
2518 inst.index_temps(fp, _globalNames);
2519
2520 // Output this instruction's encodings
2521 const char *ec_name;
2522 bool user_defined = false;
2523 encode->reset();
2524 while ((ec_name = encode->encode_class_iter()) != NULL) {
2525 fprintf(fp, " {\n");
2526 // Output user-defined encoding
2527 user_defined = true;
2528
2529 const char *ec_code = NULL;
2530 const char *ec_rep_var = NULL;
2531 EncClass *encoding = _encode->encClass(ec_name);
2532 if (encoding == NULL) {
2533 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2534 abort();
2535 }
2536
2537 if (encode->current_encoding_num_args() != encoding->num_args()) {
2538 globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2539 inst._ident, encode->current_encoding_num_args(),
2540 ec_name, encoding->num_args());
2541 }
2542
2543 DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2544 encoding->_code.reset();
2545 encoding->_rep_vars.reset();
2546 // Process list of user-defined strings,
2547 // and occurrences of replacement variables.
2548 // Replacement Vars are pushed into a list and then output
2549 while ((ec_code = encoding->_code.iter()) != NULL) {
2550 if (!encoding->_code.is_signal(ec_code)) {
2551 // Emit pending code
2552 pending.emit();
2553 pending.clear();
2554 // Emit this code section
2555 fprintf(fp, "%s", ec_code);
2556 } else {
2557 // A replacement variable or one of its subfields
2558 // Obtain replacement variable from list
2559 ec_rep_var = encoding->_rep_vars.iter();
2560 pending.add_rep_var(ec_rep_var);
2561 }
2562 }
2563 // Emit pending code
2564 pending.emit();
2565 pending.clear();
2566 fprintf(fp, " }\n");
2567 } // end while instruction's encodings
2568
2569 // Check if user stated which encoding to user
2570 if ( user_defined == false ) {
2571 fprintf(fp, " // User did not define which encode class to use.\n");
2572 }
2573
2574 // (3) and (4)
2575 fprintf(fp, "}\n");
2576 }
2577
2578 // defineEvalConstant ---------------------------------------------------------
2579 void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
2580 InsEncode* encode = inst._constant;
2581
2582 // (1)
2583 // Output instruction's emit prototype
2584 fprintf(fp, "void %sNode::eval_constant() {\n", inst._ident);
2585
2586 // For ideal jump nodes, allocate a jump table.
2587 if (inst.is_ideal_jump()) {
2588 fprintf(fp, " allocate_jump_table_in_constant_table();\n");
2589 }
2590
2591 // If user did not define an encode section,
2592 // provide stub that does not generate any machine code.
2593 if ((_encode == NULL) || (encode == NULL)) {
2594 fprintf(fp, " // User did not define an encode section.\n");
2595 fprintf(fp, "}\n");
2596 return;
2597 }
2598
2599 // Output this instruction's encodings
2600 const char *ec_name;
2601 bool user_defined = false;
2602 encode->reset();
2603 while ((ec_name = encode->encode_class_iter()) != NULL) {
2604 fprintf(fp, " {\n");
2605 // Output user-defined encoding
2606 user_defined = true;
2607
2608 const char *ec_code = NULL;
2609 const char *ec_rep_var = NULL;
2610 EncClass *encoding = _encode->encClass(ec_name);
2611 if (encoding == NULL) {
2612 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2613 abort();
2614 }
2615
2616 if (encode->current_encoding_num_args() != encoding->num_args()) {
2617 globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2618 inst._ident, encode->current_encoding_num_args(),
2619 ec_name, encoding->num_args());
2620 }
2621
2622 DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2623 encoding->_code.reset();
2624 encoding->_rep_vars.reset();
2625 // Process list of user-defined strings,
2626 // and occurrences of replacement variables.
2627 // Replacement Vars are pushed into a list and then output
2628 while ((ec_code = encoding->_code.iter()) != NULL) {
2629 if (!encoding->_code.is_signal(ec_code)) {
2630 // Emit pending code
2631 pending.emit();
2632 pending.clear();
2633 // Emit this code section
2634 fprintf(fp, "%s", ec_code);
2635 } else {
2636 // A replacement variable or one of its subfields
2637 // Obtain replacement variable from list
2638 ec_rep_var = encoding->_rep_vars.iter();
2639 pending.add_rep_var(ec_rep_var);
2640 }
2641 }
2642 // Emit pending code
2643 pending.emit();
2644 pending.clear();
2645 fprintf(fp, " }\n");
2646 } // end while instruction's encodings
2647
2648 // Check if user stated which encoding to user
2649 if (user_defined == false) {
2650 fprintf(fp, " // User did not define which encode class to use.\n");
2651 }
2652
2653 // (3) and (4)
2654 fprintf(fp, "}\n");
2655 }
2656
2657 // ---------------------------------------------------------------------------
2658 //--------Utilities to build MachOper and MachNode derived Classes------------
2659 // ---------------------------------------------------------------------------
2660
2661 //------------------------------Utilities to build Operand Classes------------
2662 static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
2663 uint num_edges = oper.num_edges(globals);
2664 if( num_edges != 0 ) {
2665 // Method header
2666 fprintf(fp, "const RegMask *%sOper::in_RegMask(int index) const {\n",
2667 oper._ident);
2668
2669 // Assert that the index is in range.
2670 fprintf(fp, " assert(0 <= index && index < %d, \"index out of range\");\n",
2671 num_edges);
2672
2673 // Figure out if all RegMasks are the same.
2674 const char* first_reg_class = oper.in_reg_class(0, globals);
3041 // Output the definitions for out_RegMask() // & kill_RegMask()
3042 _instructions.reset();
3043 InstructForm *instr;
3044 MachNodeForm *machnode;
3045 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3046 // Ensure this is a machine-world instruction
3047 if ( instr->ideal_only() ) continue;
3048
3049 defineOut_RegMask(_CPP_MISC_file._fp, instr->_ident, reg_mask(*instr));
3050 }
3051
3052 bool used = false;
3053 // Output the definitions for expand rules & peephole rules
3054 _instructions.reset();
3055 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3056 // Ensure this is a machine-world instruction
3057 if ( instr->ideal_only() ) continue;
3058 // If there are multiple defs/kills, or an explicit expand rule, build rule
3059 if( instr->expands() || instr->needs_projections() ||
3060 instr->has_temps() ||
3061 instr->is_mach_constant() ||
3062 instr->_matrule != NULL &&
3063 instr->num_opnds() != instr->num_unique_opnds() )
3064 defineExpand(_CPP_EXPAND_file._fp, instr);
3065 // If there is an explicit peephole rule, build it
3066 if ( instr->peepholes() )
3067 definePeephole(_CPP_PEEPHOLE_file._fp, instr);
3068
3069 // Output code to convert to the cisc version, if applicable
3070 used |= instr->define_cisc_version(*this, fp);
3071
3072 // Output code to convert to the short branch version, if applicable
3073 used |= instr->define_short_branch_methods(*this, fp);
3074 }
3075
3076 // Construct the method called by cisc_version() to copy inputs and operands.
3077 define_fill_new_machnode(used, fp);
3078
3079 // Output the definitions for labels
3080 _instructions.reset();
3081 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
3122 fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident);
3123 fprintf(fp, " return %d;\n", reloc_size );
3124 fprintf(fp,"}\n");
3125 fprintf(fp,"\n");
3126 }
3127 }
3128 fprintf(fp,"\n");
3129
3130 // Output the definitions for code generation
3131 //
3132 // address ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
3133 // // ... encoding defined by user
3134 // return ptr;
3135 // }
3136 //
3137 _instructions.reset();
3138 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3139 // Ensure this is a machine-world instruction
3140 if ( instr->ideal_only() ) continue;
3141
3142 if (instr->_insencode) defineEmit (fp, *instr);
3143 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
3144 if (instr->_size) defineSize (fp, *instr);
3145
3146 // side-call to generate output that used to be in the header file:
3147 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
3148 gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
3149 }
3150
3151 // Output the definitions for alias analysis
3152 _instructions.reset();
3153 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3154 // Ensure this is a machine-world instruction
3155 if ( instr->ideal_only() ) continue;
3156
3157 // Analyze machine instructions that either USE or DEF memory.
3158 int memory_operand = instr->memory_operand(_globalNames);
3159 // Some guys kill all of memory
3160 if ( instr->is_wide_memory_kill(_globalNames) ) {
3161 memory_operand = InstructForm::MANY_MEMORY_OPERANDS;
3162 }
3163
3164 if ( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
|