void test4() { QAxObjectPtr xcom(new QAxObject("{717b131f-e3dd-4053-87a6-c4e2b2e983c2}")); if (xcom->isNull()) { return; } QAxObjectPtr com(new QAxObject("{4701EA53-53D6-4F06-86A2-B211A4F84000}")); if (com->isNull()) { return; } { int value = 0; QList<QVariant> vars; vars << 10; vars << 20; vars << 0; com->dynamicCall("Add(int,int,int&)", vars); value = vars[2].toInt(); qDebug() << "answer = " << value; } { IDispatch* disp = 0; QUuid id("{00020400-0000-0000-C000-000000000046}"); com->queryInterface(id, (void**)&disp); if (disp) { WDispatchDriver driver; driver.Attach(disp); disp->Release(); short data[10]; int len = 0; VARIANT* v = driver.InvokeMethod("GetSampleArrayData", 10, data, &len); Q_ASSERT(len==8); } } }
/* * calculate addressability as follows * REGISTER ==> 12 register * NAME ==> 11 name+value(SB/SP) * note that 10 is no longer generated * CONST ==> 20 $value * *(20) ==> 21 value * &(10) ==> 12 $name+value(SB) * &(11) ==> 1 $name+value(SP) * (12) + (20) ==> 12 fold constants * (1) + (20) ==> 1 fold constants * *(12) ==> 10 back to name * *(1) ==> 11 back to name * * (2,10,11) + (20) ==> 2 indirect w offset * (2) ==> &13 * *(10,11) ==> 13 indirect, no index * * (20) * (X) ==> 7 multiplier in indexing * (X,7) + (12,1) ==> 8 adder in indexing (addresses) * (X,7) + (10,11,2) ==> 8 adder in indexing (names) * (8) ==> &9 index, almost addressable * * (X)++ ==> X fake addressability * * calculate complexity (number of registers) */ void xcom(Node *n) { Node *l, *r; int g; if(n == Z) return; l = n->left; r = n->right; n->complex = 0; n->addable = 0; switch(n->op) { case OCONST: n->addable = 20; break; case ONAME: n->addable = 11; /* difference to make relocatable */ break; case OREGISTER: n->addable = 12; break; case OADDR: xcom(l); if(l->addable == 10) n->addable = 12; else if(l->addable == 11) n->addable = 1; break; case OADD: xcom(l); xcom(r); if(n->type->etype != TIND) break; if(l->addable == 20) switch(r->addable) { case 12: case 1: n->addable = r->addable; goto brk; } if(r->addable == 20) switch(l->addable) { case 12: case 1: n->addable = l->addable; goto brk; } break; case OIND: xcom(l); if(l->op == OADDR) { l = l->left; l->type = n->type; *n = *l; return; } switch(l->addable) { case 20: n->addable = 21; break; case 1: n->addable = 11; break; case 12: n->addable = 10; break; } break; case OASHL: xcom(l); xcom(r); if(typev[n->type->etype]) break; g = vconst(r); if(g >= 0 && g < 4) n->addable = 7; break; case OMUL: case OLMUL: xcom(l); xcom(r); if(typev[n->type->etype]) break; g = vlog(r); if(g >= 0) { n->op = OASHL; r->vconst = g; if(g < 4) n->addable = 7; break; } g = vlog(l); if(g >= 0) { n->left = r; n->right = l; l = r; r = n->right; n->op = OASHL; r->vconst = g; if(g < 4) n->addable = 7; break; } break; case ODIV: case OLDIV: xcom(l); xcom(r); if(typev[n->type->etype]) break; g = vlog(r); if(g >= 0) { if(n->op == ODIV) n->op = OASHR; else n->op = OLSHR; r->vconst = g; } break; case OSUB: xcom(l); xcom(r); if(typev[n->type->etype]) break; if(vconst(l) == 0) { n->op = ONEG; n->left = r; n->right = Z; } break; case OXOR: xcom(l); xcom(r); if(typev[n->type->etype]) break; if(vconst(l) == -1) { n->op = OCOM; n->left = r; n->right = Z; } break; case OASMUL: case OASLMUL: xcom(l); xcom(r); if(typev[n->type->etype]) break; g = vlog(r); if(g >= 0) { n->op = OASASHL; r->vconst = g; } goto aseae; case OASDIV: case OASLDIV: xcom(l); xcom(r); if(typev[n->type->etype]) break; g = vlog(r); if(g >= 0) { if(n->op == OASDIV) n->op = OASASHR; else n->op = OASLSHR; r->vconst = g; } goto aseae; case OASLMOD: case OASMOD: xcom(l); xcom(r); if(typev[n->type->etype]) break; aseae: /* hack that there are no byte/short mul/div operators */ if(n->type->etype == TCHAR || n->type->etype == TSHORT) { n->right = new1(OCAST, n->right, Z); n->right->type = types[TLONG]; n->type = types[TLONG]; } if(n->type->etype == TUCHAR || n->type->etype == TUSHORT) { n->right = new1(OCAST, n->right, Z); n->right->type = types[TULONG]; n->type = types[TULONG]; } goto asop; case OASXOR: case OASOR: case OASADD: case OASSUB: case OASLSHR: case OASASHR: case OASASHL: case OASAND: case OAS: xcom(l); xcom(r); if(typev[n->type->etype]) break; asop: if(l->addable > INDEXED && l->complex < FNX && r && r->complex < FNX) n->addable = l->addable; break; case OPOSTINC: case OPREINC: case OPOSTDEC: case OPREDEC: xcom(l); if(typev[n->type->etype]) break; if(l->addable > INDEXED && l->complex < FNX) n->addable = l->addable; break; default: if(l != Z) xcom(l); if(r != Z) xcom(r); break; } brk: n->complex = 0; if(n->addable >= 10) return; if(l != Z) n->complex = l->complex; if(r != Z) { if(r->complex == n->complex) n->complex = r->complex+1; else if(r->complex > n->complex) n->complex = r->complex; } if(n->complex == 0) n->complex++; if(com64(n)) return; switch(n->op) { case OFUNC: n->complex = FNX; break; case OADD: case OMUL: case OLMUL: case OXOR: case OAND: case OOR: /* * symmetric operators, make right side simple * if same, put constant on left to get movq */ if(r->complex > l->complex || (r->complex == l->complex && r->addable == 20)) { n->left = r; n->right = l; } break; case OLE: case OLT: case OGE: case OGT: case OEQ: case ONE: /* * relational operators, make right side simple * if same, put constant on left to get movq */ if(r->complex > l->complex || r->addable == 20) { n->left = r; n->right = l; n->op = invrel[relindex(n->op)]; } break; } }
/* * calculate addressability as follows * CONST ==> 20 $value * NAME ==> 10 name * REGISTER ==> 11 register * INDREG ==> 12 *[(reg)+offset] * &10 ==> 2 $name * ADD(2, 20) ==> 2 $name+offset * ADD(3, 20) ==> 3 $(reg)+offset * &12 ==> 3 $(reg)+offset * *11 ==> 11 ?? * *2 ==> 10 name * *3 ==> 12 *(reg)+offset * calculate complexity (number of registers) */ void xcom(Node *n) { Node *l, *r; int t; if(n == Z) return; l = n->left; r = n->right; n->addable = 0; n->complex = 0; switch(n->op) { case OCONST: n->addable = 20; return; case OREGISTER: n->addable = 11; return; case OINDREG: n->addable = 12; return; case ONAME: n->addable = 10; return; case OADDR: xcom(l); if(l->addable == 10) n->addable = 2; if(l->addable == 12) n->addable = 3; break; case OIND: xcom(l); if(l->addable == 11) n->addable = 12; if(l->addable == 3) n->addable = 12; if(l->addable == 2) n->addable = 10; break; case OADD: xcom(l); xcom(r); if(l->addable == 20) { if(r->addable == 2) n->addable = 2; if(r->addable == 3) n->addable = 3; } if(r->addable == 20) { if(l->addable == 2) n->addable = 2; if(l->addable == 3) n->addable = 3; } break; /* case OSUB: xcom(l); xcom(r); if(typefd[n->type->etype] || typev[n->type->etype]) break; if(vconst(l) == 0) n->op = ONEG; n->left = l; n->right = Z; } break; */ case OASHL: case OASHR: case OLSHR: case OASASHL: case OASASHR: case OASLSHR: xcom(l); xcom(r); if(sconst(r) && r->vconst < 0){ r->vconst = -r->vconst; switch(n->op){ case OASHL: n->op = OASHR; break; case OASHR: n->op = OASHL; break; case OLSHR: n->op = OASHL; break; case OASASHL: n->op = OASASHR; break; case OASASHR: n->op = OASASHL; break; case OASLSHR: n->op = OASASHL; break; } } break; case OASLMUL: case OASMUL: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASASHL; r->vconst = t; r->type = types[TINT]; } break; case OMUL: case OLMUL: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASHL; r->vconst = t; r->type = types[TINT]; } t = vlog(l); if(t >= 0) { n->op = OASHL; n->left = r; n->right = l; r = l; l = n->left; r->vconst = t; r->type = types[TINT]; } break; case OASLDIV: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASLSHR; r->vconst = t; r->type = types[TINT]; } break; case OLDIV: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OLSHR; r->vconst = t; r->type = types[TINT]; } break; case OASLMOD: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASAND; r->vconst--; } break; case OLMOD: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OAND; r->vconst--; } break; default: if(l != Z) xcom(l); if(r != Z) xcom(r); break; } if(n->addable >= 10) return; if(l != Z) n->complex = l->complex; if(r != Z) { if(r->complex == n->complex) n->complex = r->complex+1; else if(r->complex > n->complex) n->complex = r->complex; } if(n->complex == 0) n->complex++; if(com64(n)) return; switch(n->op) { case OFUNC: n->complex = FNX; break; case OLE: case OLT: case OGE: case OGT: case OHI: case OHS: case OLO: case OLS: /* * immediate operators, make const on right */ if(l->op == OCONST) { n->left = r; n->right = l; n->op = invrel[relindex(n->op)]; } break; case OADD: case OXOR: case OAND: case OOR: case OEQ: case ONE: /* * immediate operators, make const on right */ if(l->op == OCONST) { n->left = r; n->right = l; } break; } }
/* * calculate addressability as follows * CONST ==> 20 $value * NAME ==> 10 name * REGISTER ==> 11 register * INDREG ==> 12 *[(reg)+offset] * &10 ==> 2 $name * ADD(2, 20) ==> 2 $name+offset * ADD(3, 20) ==> 3 $(reg)+offset * &12 ==> 3 $(reg)+offset * *11 ==> 11 ?? * *2 ==> 10 name * *3 ==> 12 *(reg)+offset * calculate complexity (number of registers) */ void xcom(Node *n) { Node *l, *r; int t; if(n == Z) return; l = n->left; r = n->right; n->addable = 0; n->complex = 0; switch(n->op) { case OCONST: n->addable = 20; return; case OREGISTER: n->addable = 11; return; case OINDREG: n->addable = 12; return; case ONAME: n->addable = 10; return; case OADDR: xcom(l); if(l->addable == 10) n->addable = 2; if(l->addable == 12) n->addable = 3; break; case OIND: xcom(l); if(l->addable == 11) n->addable = 12; if(l->addable == 3) n->addable = 12; if(l->addable == 2) n->addable = 10; break; case OADD: xcom(l); xcom(r); if(l->addable == 20) { if(r->addable == 2) n->addable = 2; if(r->addable == 3) n->addable = 3; } if(r->addable == 20) { if(l->addable == 2) n->addable = 2; if(l->addable == 3) n->addable = 3; } break; case OASLMUL: case OASMUL: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASASHL; r->vconst = t; r->type = types[TINT]; } break; case OMUL: case OLMUL: xcom(l); xcom(r); t = vlog(l); if(t >= 0) { n->left = r; n->right = l; l = r; r = n->right; } t = vlog(r); if(t >= 0) { n->op = OASHL; r->vconst = t; r->type = types[TINT]; simplifyshift(n); } break; case OASLDIV: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASLSHR; r->vconst = t; r->type = types[TINT]; } break; case OLDIV: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OLSHR; r->vconst = t; r->type = types[TINT]; simplifyshift(n); } break; case OASLMOD: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OASAND; r->vconst--; } break; case OLMOD: xcom(l); xcom(r); t = vlog(r); if(t >= 0) { n->op = OAND; r->vconst--; } break; case OLSHR: case OASHL: case OASHR: xcom(l); xcom(r); simplifyshift(n); break; default: if(l != Z) xcom(l); if(r != Z) xcom(r); break; } if(n->addable >= 10) return; if(l != Z) n->complex = l->complex; if(r != Z) { if(r->complex == n->complex) n->complex = r->complex+1; else if(r->complex > n->complex) n->complex = r->complex; } if(n->complex == 0) n->complex++; if(com64(n)) return; switch(n->op) { case OFUNC: n->complex = FNX; break; case OADD: case OXOR: case OAND: case OOR: case OEQ: case ONE: /* * immediate operators, make const on right */ if(l->op == OCONST) { n->left = r; n->right = l; } break; } }