============ idCompiler::OptimizeOpcode try to optimize when the operator works on constants only ============ */
| 488 | ============ |
| 489 | */ |
| 490 | idVarDef *idCompiler::OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ) { |
| 491 | eval_t c; |
| 492 | idTypeDef *type; |
| 493 | |
| 494 | if ( var_a && var_a->initialized != idVarDef::initializedConstant ) { |
| 495 | return NULL; |
| 496 | } |
| 497 | if ( var_b && var_b->initialized != idVarDef::initializedConstant ) { |
| 498 | return NULL; |
| 499 | } |
| 500 | |
| 501 | idVec3 &vec_c = *reinterpret_cast<idVec3 *>( &c.vector[ 0 ] ); |
| 502 | |
| 503 | memset( &c, 0, sizeof( c ) ); |
| 504 | switch( op - opcodes ) { |
| 505 | case OP_ADD_F: c._float = *var_a->value.floatPtr + *var_b->value.floatPtr; type = &type_float; break; |
| 506 | case OP_ADD_V: vec_c = *var_a->value.vectorPtr + *var_b->value.vectorPtr; type = &type_vector; break; |
| 507 | case OP_SUB_F: c._float = *var_a->value.floatPtr - *var_b->value.floatPtr; type = &type_float; break; |
| 508 | case OP_SUB_V: vec_c = *var_a->value.vectorPtr - *var_b->value.vectorPtr; type = &type_vector; break; |
| 509 | case OP_MUL_F: c._float = *var_a->value.floatPtr * *var_b->value.floatPtr; type = &type_float; break; |
| 510 | case OP_MUL_V: c._float = *var_a->value.vectorPtr * *var_b->value.vectorPtr; type = &type_float; break; |
| 511 | case OP_MUL_FV: vec_c = *var_b->value.vectorPtr * *var_a->value.floatPtr; type = &type_vector; break; |
| 512 | case OP_MUL_VF: vec_c = *var_a->value.vectorPtr * *var_b->value.floatPtr; type = &type_vector; break; |
| 513 | case OP_DIV_F: c._float = Divide( *var_a->value.floatPtr, *var_b->value.floatPtr ); type = &type_float; break; |
| 514 | case OP_MOD_F: c._float = (int)*var_a->value.floatPtr % (int)*var_b->value.floatPtr; type = &type_float; break; |
| 515 | case OP_BITAND: c._float = ( int )*var_a->value.floatPtr & ( int )*var_b->value.floatPtr; type = &type_float; break; |
| 516 | case OP_BITOR: c._float = ( int )*var_a->value.floatPtr | ( int )*var_b->value.floatPtr; type = &type_float; break; |
| 517 | case OP_GE: c._float = *var_a->value.floatPtr >= *var_b->value.floatPtr; type = &type_float; break; |
| 518 | case OP_LE: c._float = *var_a->value.floatPtr <= *var_b->value.floatPtr; type = &type_float; break; |
| 519 | case OP_GT: c._float = *var_a->value.floatPtr > *var_b->value.floatPtr; type = &type_float; break; |
| 520 | case OP_LT: c._float = *var_a->value.floatPtr < *var_b->value.floatPtr; type = &type_float; break; |
| 521 | case OP_AND: c._float = *var_a->value.floatPtr && *var_b->value.floatPtr; type = &type_float; break; |
| 522 | case OP_OR: c._float = *var_a->value.floatPtr || *var_b->value.floatPtr; type = &type_float; break; |
| 523 | case OP_NOT_BOOL: c._int = !*var_a->value.intPtr; type = &type_boolean; break; |
| 524 | case OP_NOT_F: c._float = !*var_a->value.floatPtr; type = &type_float; break; |
| 525 | case OP_NOT_V: c._float = !var_a->value.vectorPtr->x && !var_a->value.vectorPtr->y && !var_a->value.vectorPtr->z; type = &type_float; break; |
| 526 | case OP_NEG_F: c._float = -*var_a->value.floatPtr; type = &type_float; break; |
| 527 | case OP_NEG_V: vec_c = -*var_a->value.vectorPtr; type = &type_vector; break; |
| 528 | case OP_INT_F: c._float = ( int )*var_a->value.floatPtr; type = &type_float; break; |
| 529 | case OP_EQ_F: c._float = ( *var_a->value.floatPtr == *var_b->value.floatPtr ); type = &type_float; break; |
| 530 | case OP_EQ_V: c._float = var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break; |
| 531 | case OP_EQ_E: c._float = ( *var_a->value.intPtr == *var_b->value.intPtr ); type = &type_float; break; |
| 532 | case OP_NE_F: c._float = ( *var_a->value.floatPtr != *var_b->value.floatPtr ); type = &type_float; break; |
| 533 | case OP_NE_V: c._float = !var_a->value.vectorPtr->Compare( *var_b->value.vectorPtr ); type = &type_float; break; |
| 534 | case OP_NE_E: c._float = ( *var_a->value.intPtr != *var_b->value.intPtr ); type = &type_float; break; |
| 535 | case OP_UADD_F: c._float = *var_b->value.floatPtr + *var_a->value.floatPtr; type = &type_float; break; |
| 536 | case OP_USUB_F: c._float = *var_b->value.floatPtr - *var_a->value.floatPtr; type = &type_float; break; |
| 537 | case OP_UMUL_F: c._float = *var_b->value.floatPtr * *var_a->value.floatPtr; type = &type_float; break; |
| 538 | case OP_UDIV_F: c._float = Divide( *var_b->value.floatPtr, *var_a->value.floatPtr ); type = &type_float; break; |
| 539 | case OP_UMOD_F: c._float = ( int ) *var_b->value.floatPtr % ( int )*var_a->value.floatPtr; type = &type_float; break; |
| 540 | case OP_UOR_F: c._float = ( int )*var_b->value.floatPtr | ( int )*var_a->value.floatPtr; type = &type_float; break; |
| 541 | case OP_UAND_F: c._float = ( int )*var_b->value.floatPtr & ( int )*var_a->value.floatPtr; type = &type_float; break; |
| 542 | case OP_UINC_F: c._float = *var_a->value.floatPtr + 1; type = &type_float; break; |
| 543 | case OP_UDEC_F: c._float = *var_a->value.floatPtr - 1; type = &type_float; break; |
| 544 | case OP_COMP_F: c._float = ( float )~( int )*var_a->value.floatPtr; type = &type_float; break; |
| 545 | default: type = NULL; break; |
| 546 | } |
| 547 |