ir.cpp
/***********************************************************************
 *IR Code-Generation
 *
 * Since the IR has the convention of putting 'write' operands
 * at the beginning, we have to rotate the operands of instructions
 * properly in order to generate valid QCVM code.
 *
 * Having destinations at a fixed position is more convenient. In QC
 * this is *mostly* OPC,  but FTE adds at least 2 instructions which
 * read from from OPA,  and store to OPB rather than OPC.   Which is
 * partially the reason why the implementation of these instructions
 * in darkplaces has been delayed for so long.
 *
 * Breaking conventions is annoying...
 */
IR Code-Generation
Since the IR has the convention of putting 'write' operands
at the beginning, we have to rotate the operands of instructions
properly in order to generate valid QCVM code.

Having destinations at a fixed position is more convenient. In QC
this is *mostly* OPC,  but FTE adds at least 2 instructions which
read from from OPA,  and store to OPB rather than OPC.   Which is
partially the reason why the implementation of these instructions
in darkplaces has been delayed for so long.

Breaking conventions is annoying
IR Code - Generation Since the IR has the convention of putting ' write ' operands at the beginning we have to rotate the operands of instructions properly in order to generate valid QCVM code . Having destinations at a fixed position is more convenient . In QC this is * mostly * OPC but FTE adds at least 2 instructions which read from from OPA and store to OPB rather than OPC . Which is partially the reason why the implementation of these instructions in darkplaces has been delayed for so long . Breaking conventions is annoying
static bool gen_global_field(code_t *code, ir_value *global)
{
    if (global->m_hasvalue)
    {
        ir_value *fld = global->m_constval.vpointer;
        if (!fld) {
            irerror(global->m_context, "Invalid field constant with no field: %s", global->m_name.c_str());
            return false;
        }
        global->setCodeAddress(code->globals.size());
        code->globals.push_back(fld->m_code.fieldaddr);
        if (global->m_fieldtype == TYPE_VECTOR) {
            code->globals.push_back(fld->m_code.fieldaddr+1);
            code->globals.push_back(fld->m_code.fieldaddr+2);
        }
    }
    else
    {
        global->setCodeAddress(code->globals.size());
        code->globals.push_back(0);
        if (global->m_fieldtype == TYPE_VECTOR) {
            code->globals.push_back(0);
            code->globals.push_back(0);
        }
    }
    if (global->m_code.globaladdr < 0)
        return false;
    return true;
}
static bool gen_global_field ( code_t * code , ir_value * global ) { if ( global -> m_hasvalue ) { ir_value * fld = global -> m_constval . vpointer ; if ( ! fld ) { irerror ( global -> m_context , " " , global -> m_name . c_str ( ) ) ; return false ; } global -> setCodeAddress ( code -> globals . size ( ) ) ; code -> globals . push_back ( fld -> m_code . fieldaddr ) ; if ( global -> m_fieldtype == TYPE_VECTOR ) { code -> globals . push_back ( fld -> m_code . fieldaddr + 1 ) ; code -> globals . push_back ( fld -> m_code . fieldaddr + 2 ) ; } } else { global -> setCodeAddress ( code -> globals . size ( ) ) ; code -> globals . push_back ( 0 ) ; if ( global -> m_fieldtype == TYPE_VECTOR ) { code -> globals . push_back ( 0 ) ; code -> globals . push_back ( 0 ) ; } } if ( global -> m_code . globaladdr < 0 ) return false ; return true ; }
IR Code-Generation
 Since the IR has the convention of putting 'write' operands
 at the beginning, we have to rotate the operands of instructions
 properly in order to generate valid QCVM code.
IR Code - Generation Since the IR has the convention of putting ' write ' operands at the beginning we have to rotate the operands of instructions properly in order to generate valid QCVM code .
/* copy the field's value */