============ idCompiler::EmitOpcode Emits a primitive statement, returning the var it places it's value in ============ */
| 573 | ============ |
| 574 | */ |
| 575 | idVarDef *idCompiler::EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) { |
| 576 | statement_t *statement; |
| 577 | idVarDef *var_c; |
| 578 | |
| 579 | var_c = OptimizeOpcode( op, var_a, var_b ); |
| 580 | if ( var_c ) { |
| 581 | return var_c; |
| 582 | } |
| 583 | |
| 584 | if ( var_a && !strcmp( var_a->Name(), RESULT_STRING ) ) { |
| 585 | var_a->numUsers++; |
| 586 | } |
| 587 | if ( var_b && !strcmp( var_b->Name(), RESULT_STRING ) ) { |
| 588 | var_b->numUsers++; |
| 589 | } |
| 590 | |
| 591 | statement = gameLocal.program.AllocStatement(); |
| 592 | statement->linenumber = currentLineNumber; |
| 593 | statement->file = currentFileNumber; |
| 594 | |
| 595 | if ( ( op->type_c == &def_void ) || op->rightAssociative ) { |
| 596 | // ifs, gotos, and assignments don't need vars allocated |
| 597 | var_c = NULL; |
| 598 | } else { |
| 599 | // allocate result space |
| 600 | // try to reuse result defs as much as possible |
| 601 | var_c = gameLocal.program.FindFreeResultDef( op->type_c->TypeDef(), RESULT_STRING, scope, var_a, var_b ); |
| 602 | // set user count back to 1, a result def needs to be used twice before it can be reused |
| 603 | var_c->numUsers = 1; |
| 604 | } |
| 605 | |
| 606 | statement->op = op - opcodes; |
| 607 | statement->a = var_a; |
| 608 | statement->b = var_b; |
| 609 | statement->c = var_c; |
| 610 | |
| 611 | if ( op->rightAssociative ) { |
| 612 | return var_a; |
| 613 | } |
| 614 | |
| 615 | return var_c; |
| 616 | } |
| 617 | |
| 618 | /* |
| 619 | ============ |
nothing calls this directly
no test coverage detected