672
677
timeout.tv_usec %= 1000000;
677
gettimeofday(&tv1, NULL);
678
if (tv1.tv_sec > timeout.tv_sec ||
679
(tv1.tv_sec == timeout.tv_sec &&
680
tv1.tv_usec > timeout.tv_usec)) {
681
cli_warnmsg("Bytecode run timed out in interpreter after %u opcodes\n", pc);
686
switch (inst->interp_op) {
687
DEFINE_BINOP(OP_BC_ADD, res = op0 + op1);
688
DEFINE_BINOP(OP_BC_SUB, res = op0 - op1);
689
DEFINE_BINOP(OP_BC_MUL, res = op0 * op1);
691
DEFINE_BINOP(OP_BC_UDIV, CHECK_OP(op1 == 0, "bytecode attempted to execute udiv#0\n");
693
DEFINE_BINOP(OP_BC_SDIV, CHECK_OP(check_sdivops(sop0, sop1), "bytecode attempted to execute sdiv#0\n");
695
DEFINE_BINOP(OP_BC_UREM, CHECK_OP(op1 == 0, "bytecode attempted to execute urem#0\n");
697
DEFINE_BINOP(OP_BC_SREM, CHECK_OP(check_sdivops(sop0,sop1), "bytecode attempted to execute urem#0\n");
700
DEFINE_BINOP(OP_BC_SHL, CHECK_OP(op1 > inst->type, "bytecode attempted to execute shl greater than bitwidth\n");
702
DEFINE_BINOP(OP_BC_LSHR, CHECK_OP(op1 > inst->type, "bytecode attempted to execute lshr greater than bitwidth\n");
704
DEFINE_BINOP(OP_BC_ASHR, CHECK_OP(op1 > inst->type, "bytecode attempted to execute ashr greater than bitwidth\n");
705
res = CLI_SRS(sop0, op1));
707
DEFINE_BINOP(OP_BC_AND, res = op0 & op1);
708
DEFINE_BINOP(OP_BC_OR, res = op0 | op1);
709
DEFINE_BINOP(OP_BC_XOR, res = op0 ^ op1);
711
DEFINE_SCASTOP(OP_BC_SEXT,
712
CHOOSE(READ1(sres, inst->u.cast.source); res = sres ? ~0ull : 0,
713
READ8(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask),
714
READ16(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask),
715
READ32(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask),
716
READ64(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask)));
717
DEFINE_CASTOP(OP_BC_ZEXT,
718
CHOOSE(READ1(res, inst->u.cast.source),
719
READ8(res, inst->u.cast.source),
720
READ16(res, inst->u.cast.source),
721
READ32(res, inst->u.cast.source),
722
READ64(res, inst->u.cast.source)));
723
DEFINE_CASTOP(OP_BC_TRUNC,
724
CHOOSE(READ1(res, inst->u.cast.source),
725
READ8(res, inst->u.cast.source),
726
READ16(res, inst->u.cast.source),
727
READ32(res, inst->u.cast.source),
728
READ64(res, inst->u.cast.source)));
730
DEFINE_OP(OP_BC_BRANCH)
731
stop = jump(func, (values[inst->u.branch.condition]&1) ?
732
inst->u.branch.br_true : inst->u.branch.br_false,
733
&bb, &inst, &bb_inst);
737
stop = jump(func, inst->u.jump, &bb, &inst, &bb_inst);
740
DEFINE_OP_BC_RET_N(OP_BC_RET*5, uint8_t, READ1, WRITE8);
741
DEFINE_OP_BC_RET_N(OP_BC_RET*5+1, uint8_t, READ8, WRITE8);
742
DEFINE_OP_BC_RET_N(OP_BC_RET*5+2, uint16_t, READ16, WRITE16);
743
DEFINE_OP_BC_RET_N(OP_BC_RET*5+3, uint32_t, READ32, WRITE32);
744
DEFINE_OP_BC_RET_N(OP_BC_RET*5+4, uint64_t, READ64, WRITE64);
746
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5, uint8_t, (void), (void));
747
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+1, uint8_t, (void), (void));
748
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+2, uint8_t, (void), (void));
749
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+3, uint8_t, (void), (void));
750
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+4, uint8_t, (void), (void));
752
DEFINE_ICMPOP(OP_BC_ICMP_EQ, res = (op0 == op1));
753
DEFINE_ICMPOP(OP_BC_ICMP_NE, res = (op0 != op1));
754
DEFINE_ICMPOP(OP_BC_ICMP_UGT, res = (op0 > op1));
755
DEFINE_ICMPOP(OP_BC_ICMP_UGE, res = (op0 >= op1));
756
DEFINE_ICMPOP(OP_BC_ICMP_ULT, res = (op0 < op1));
757
DEFINE_ICMPOP(OP_BC_ICMP_ULE, res = (op0 <= op1));
758
DEFINE_ICMPOP(OP_BC_ICMP_SGT, res = (sop0 > sop1));
759
DEFINE_ICMPOP(OP_BC_ICMP_SGE, res = (sop0 >= sop1));
760
DEFINE_ICMPOP(OP_BC_ICMP_SLE, res = (sop0 <= sop1));
761
DEFINE_ICMPOP(OP_BC_ICMP_SLT, res = (sop0 < sop1));
766
READ1(t0, inst->u.three[0]);
767
READ1(t1, inst->u.three[1]);
768
READ1(t2, inst->u.three[2]);
769
WRITE8(inst->dest, t0 ? t1 : t2);
772
case OP_BC_SELECT*5+1:
775
READ1(t0, inst->u.three[0]);
776
READ8(t1, inst->u.three[1]);
777
READ8(t2, inst->u.three[2]);
778
WRITE8(inst->dest, t0 ? t1 : t2);
781
case OP_BC_SELECT*5+2:
785
READ1(t0, inst->u.three[0]);
786
READ16(t1, inst->u.three[1]);
787
READ16(t2, inst->u.three[2]);
788
WRITE16(inst->dest, t0 ? t1 : t2);
791
case OP_BC_SELECT*5+3:
795
READ1(t0, inst->u.three[0]);
796
READ32(t1, inst->u.three[1]);
797
READ32(t2, inst->u.three[2]);
798
WRITE32(inst->dest, t0 ? t1 : t2);
801
case OP_BC_SELECT*5+4:
805
READ1(t0, inst->u.three[0]);
806
READ64(t1, inst->u.three[1]);
807
READ64(t2, inst->u.three[2]);
808
WRITE64(inst->dest, t0 ? t1 : t2);
812
DEFINE_OP(OP_BC_CALL_API) {
813
const struct cli_apicall *api = &cli_apicalls[inst->u.ops.funcid];
816
CHECK_APIID(inst->u.ops.funcid);
817
TRACE_API(api->name, inst->dest, inst->type, stack_depth);
821
READ32(a, inst->u.ops.ops[0]);
822
READ32(b, inst->u.ops.ops[1]);
823
res32 = cli_apicalls0[api->idx](ctx, a, b);
824
WRITE32(inst->dest, res32);
830
unsigned arg2, arg1size;
831
READ32(arg2, inst->u.ops.ops[1]);
832
/* check that arg2 is size of arg1 */
834
for (i=0;i<sizeof(apisize_override)/sizeof(apisize_override[0]);i++) {
835
if (cli_apicalls1[api->idx] == apisize_override[i].api) {
836
arg1size = apisize_override[i].override_size;
840
READPOP(arg1, inst->u.ops.ops[0], arg1size);
841
res32 = cli_apicalls1[api->idx](ctx, arg1, arg2);
842
WRITE32(inst->dest, res32);
847
READ32(a, inst->u.ops.ops[0]);
848
res32 = cli_apicalls2[api->idx](ctx, a);
849
WRITE32(inst->dest, res32);
855
READ32(a, inst->u.ops.ops[0]);
856
resp = cli_apicalls3[api->idx](ctx, a);
857
res64 = ptr_register_glob(&ptrinfos, resp, a);
858
WRITE64(inst->dest, res64);
862
int32_t arg2, arg3, arg4, arg5;
864
READ32(arg2, inst->u.ops.ops[1]);
865
/* check that arg2 is size of arg1 */
866
READP(arg1, inst->u.ops.ops[0], arg2);
867
READ32(arg3, inst->u.ops.ops[2]);
868
READ32(arg4, inst->u.ops.ops[3]);
869
READ32(arg5, inst->u.ops.ops[4]);
870
res32 = cli_apicalls4[api->idx](ctx, arg1, arg2, arg3, arg4, arg5);
871
WRITE32(inst->dest, res32);
875
res32 = cli_apicalls5[api->idx](ctx);
876
WRITE32(inst->dest, res32);
882
READ32(arg1, inst->u.ops.ops[0]);
883
READ32(arg2, inst->u.ops.ops[1]);
884
resp = cli_apicalls6[api->idx](ctx, arg1, arg2);
885
res64 = ptr_register_glob(&ptrinfos, resp, arg2);
886
WRITE64(inst->dest, res64);
890
int32_t arg1,arg2,arg3;
891
READ32(arg1, inst->u.ops.ops[0]);
892
READ32(arg2, inst->u.ops.ops[1]);
893
READ32(arg3, inst->u.ops.ops[2]);
894
res32 = cli_apicalls7[api->idx](ctx, arg1, arg2, arg3);
895
WRITE32(inst->dest, res32);
902
READ32(arg2, inst->u.ops.ops[1]);
903
/* check that arg2 is size of arg1 */
904
READP(arg1, inst->u.ops.ops[0], arg2);
905
READ32(arg4, inst->u.ops.ops[3]);
906
READP(arg3, inst->u.ops.ops[2], arg4);
907
resp = cli_apicalls8[api->idx](ctx, arg1, arg2, arg3, arg4);
908
WRITE32(inst->dest, resp);
915
READ32(arg2, inst->u.ops.ops[1]);
916
/* check that arg2 is size of arg1 */
917
READP(arg1, inst->u.ops.ops[0], arg2);
918
READ32(arg3, inst->u.ops.ops[2]);
919
resp = cli_apicalls9[api->idx](ctx, arg1, arg2, arg3);
920
WRITE32(inst->dest, resp);
924
cli_warnmsg("bytecode: type %u apicalls not yet implemented!\n", api->kind);
930
DEFINE_OP(OP_BC_CALL_DIRECT)
931
CHECK_FUNCID(inst->u.ops.funcid);
932
func2 = &bc->funcs[inst->u.ops.funcid];
933
CHECK_EQ(func2->numArgs, inst->u.ops.numOps);
935
stack_entry = allocate_stack(&stack, stack_entry, func2, func, inst->dest,
941
values = stack_entry->values;
942
/* TODO: unregister on ret */
943
TRACE_EXEC(inst->u.ops.funcid, inst->dest, inst->type, stack_depth);
944
if (stack_depth > 10000) {
945
cli_warnmsg("bytecode: stack depth exceeded\n");
950
for (i=0;i<func2->numArgs;i++) {
951
switch (inst->u.ops.opsizes[i]) {
954
READOLD8(v, inst->u.ops.ops[i]);
955
CHECK_GT(func2->numBytes, j);
961
READOLD16(v, inst->u.ops.ops[i]);
963
CHECK_GT(func2->numBytes, j);
964
*(uint16_t*)&values[j] = v;
970
READOLD32(v, inst->u.ops.ops[i]);
972
CHECK_GT(func2->numBytes, j);
973
*(uint32_t*)&values[j] = v;
979
READOLD64(v, inst->u.ops.ops[i]);
981
CHECK_GT(func2->numBytes, j);
982
*(uint64_t*)&values[j] = v;
989
stackid = ptr_register_stack(&ptrinfos, values, 0, func->numBytes)>>32;
990
CHECK_GT(func->numBB, 0);
991
stop = jump(func, 0, &bb, &inst, &bb_inst);
999
WRITE8(BINOP(1), op);
1002
case OP_BC_COPY*5+1:
1005
READ8(op, BINOP(0));
1006
WRITE8(BINOP(1), op);
1009
case OP_BC_COPY*5+2:
1012
READ16(op, BINOP(0));
1013
WRITE16(BINOP(1), op);
1016
case OP_BC_COPY*5+3:
1019
READ32(op, BINOP(0));
1020
WRITE32(BINOP(1), op);
1023
case OP_BC_COPY*5+4:
1026
READ64(op, BINOP(0));
1027
WRITE64(BINOP(1), op);
1032
case OP_BC_LOAD*5+1:
1035
READPOP(ptr, inst->u.unaryop, 1);
1036
WRITE8(inst->dest, (*ptr));
1039
case OP_BC_LOAD*5+2:
1041
const union unaligned_16 *ptr;
1042
READPOP(ptr, inst->u.unaryop, 2);
1043
WRITE16(inst->dest, (ptr->una_u16));
1046
case OP_BC_LOAD*5+3:
1048
const union unaligned_32 *ptr;
1049
READPOP(ptr, inst->u.unaryop, 4);
1050
WRITE32(inst->dest, (ptr->una_u32));
1053
case OP_BC_LOAD*5+4:
1055
const union unaligned_64 *ptr;
1056
READPOP(ptr, inst->u.unaryop, 8);
1057
WRITE64(inst->dest, (ptr->una_u64));
1065
READP(ptr, BINOP(1), 1);
1070
case OP_BC_STORE*5+1:
1074
READP(ptr, BINOP(1), 1);
1079
case OP_BC_STORE*5+2:
1081
union unaligned_16 *ptr;
1083
READP(ptr, BINOP(1), 2);
1084
READ16(v, BINOP(0));
1088
case OP_BC_STORE*5+3:
1090
union unaligned_32 *ptr;
1092
READP(ptr, BINOP(1), 4);
1093
READ32(v, BINOP(0));
1097
case OP_BC_STORE*5+4:
1099
union unaligned_64 *ptr;
1101
READP(ptr, BINOP(1), 8);
1102
READ64(v, BINOP(0));
1106
DEFINE_OP(OP_BC_ISBIGENDIAN) {
1107
WRITE8(inst->dest, WORDS_BIGENDIAN);
1110
DEFINE_OP(OP_BC_GEPZ) {
1112
if (!(inst->interp_op%5)) {
1114
READ32(off, inst->u.three[2]);
1115
WRITE64(inst->dest, ptr_compose(stackid,
1116
inst->u.three[1]+off));
1119
READ32(off, inst->u.three[2]);
1120
READ64(ptr, inst->u.three[1]);
1121
WRITE64(inst->dest, ptr+off);
1125
DEFINE_OP(OP_BC_MEMCMP) {
1128
READ32(arg3, inst->u.three[2]);
1129
READPOP(arg1, inst->u.three[0], arg3);
1130
READPOP(arg2, inst->u.three[1], arg3);
1131
WRITE32(inst->dest, memcmp(arg1, arg2, arg3));
1134
DEFINE_OP(OP_BC_MEMCPY) {
1139
READ32(arg3, inst->u.three[2]);
1140
READPOP(arg1, inst->u.three[0], arg3);
1141
READPOP(arg2, inst->u.three[1], arg3);
1142
memcpy(arg1, arg2, (int32_t)arg3);
1143
/* READ64(res, inst->u.three[0]);*/
1144
WRITE64(inst->dest, res);
1147
DEFINE_OP(OP_BC_MEMMOVE) {
1152
READ64(arg3, inst->u.three[2]);
1153
READPOP(arg1, inst->u.three[0], arg3);
1154
READPOP(arg2, inst->u.three[1], arg3);
1155
memmove(arg1, arg2, (int32_t)arg3);
1156
/* READ64(res, inst->u.three[0]);*/
1157
WRITE64(inst->dest, res);
1160
DEFINE_OP(OP_BC_MEMSET) {
1166
READ64(arg3, inst->u.three[2]);
1167
READPOP(arg1, inst->u.three[0], arg3);
1168
READ32(arg2, inst->u.three[1]);
1169
memset(arg1, arg2, (int32_t)arg3);
1170
/* READ64(res, inst->u.three[0]);*/
1171
WRITE64(inst->dest, res);
1174
DEFINE_OP(OP_BC_BSWAP16) {
1176
READ16(arg1, inst->u.unaryop);
1177
WRITE16(inst->dest, cbswap16(arg1));
1180
DEFINE_OP(OP_BC_BSWAP32) {
1182
READ32(arg1, inst->u.unaryop);
1183
WRITE32(inst->dest, cbswap32(arg1));
1186
DEFINE_OP(OP_BC_BSWAP64) {
1188
READ64(arg1, inst->u.unaryop);
1189
WRITE64(inst->dest, cbswap64(arg1));
1192
DEFINE_OP(OP_BC_PTRDIFF32) {
1194
if (BINOP(0)&0x40000000)
1195
ptr1 = ptr_compose(stackid, BINOP(0)&0xbfffffff);
1197
READ64(ptr1, BINOP(0));
1198
if (BINOP(1)&0x40000000)
1199
ptr2 = ptr_compose(stackid, BINOP(1)&0xbfffffff);
1201
READ64(ptr2, BINOP(1));
1202
WRITE32(inst->dest, ptr_diff32(ptr1, ptr2));
1205
DEFINE_OP(OP_BC_PTRTOINT64) {
1207
if (inst->u.unaryop&0x40000000)
1208
ptr = ptr_compose(stackid, inst->u.unaryop&0xbfffffff);
1210
READ64(ptr, BINOP(0));
1211
WRITE64(inst->dest, ptr);
1214
DEFINE_OP(OP_BC_GEP1) {
1216
if (!(inst->interp_op%5)) {
1218
READ32(off, inst->u.three[2]);
1219
WRITE64(inst->dest, ptr_compose(stackid,
1220
inst->u.three[1]+off*inst->u.three[0]));
1223
READ32(off, inst->u.three[2]);
1224
READ64(ptr, inst->u.three[1]);
1225
WRITE64(inst->dest, ptr+off*inst->u.three[0]);
1229
/* TODO: implement OP_BC_GEP1, OP_BC_GEP2, OP_BC_GEPN */
1231
cli_errmsg("Opcode %u of type %u is not implemented yet!\n",
1232
inst->interp_op/5, inst->interp_op%5);
1239
CHECK_GT(bb->numInsts, bb_inst);
682
gettimeofday(&tv1, NULL);
683
if (tv1.tv_sec > timeout.tv_sec ||
684
(tv1.tv_sec == timeout.tv_sec &&
685
tv1.tv_usec > timeout.tv_usec)) {
686
cli_warnmsg("Bytecode run timed out in interpreter after %u opcodes\n", pc);
691
switch (inst->interp_op) {
692
DEFINE_BINOP(OP_BC_ADD, res = op0 + op1);
693
DEFINE_BINOP(OP_BC_SUB, res = op0 - op1);
694
DEFINE_BINOP(OP_BC_MUL, res = op0 * op1);
696
DEFINE_BINOP(OP_BC_UDIV, CHECK_OP(op1 == 0, "bytecode attempted to execute udiv#0\n");
698
DEFINE_BINOP(OP_BC_SDIV, CHECK_OP(check_sdivops(sop0, sop1), "bytecode attempted to execute sdiv#0\n");
700
DEFINE_BINOP(OP_BC_UREM, CHECK_OP(op1 == 0, "bytecode attempted to execute urem#0\n");
702
DEFINE_BINOP(OP_BC_SREM, CHECK_OP(check_sdivops(sop0,sop1), "bytecode attempted to execute urem#0\n");
705
DEFINE_BINOP(OP_BC_SHL, CHECK_OP(op1 > inst->type, "bytecode attempted to execute shl greater than bitwidth\n");
707
DEFINE_BINOP(OP_BC_LSHR, CHECK_OP(op1 > inst->type, "bytecode attempted to execute lshr greater than bitwidth\n");
709
DEFINE_BINOP(OP_BC_ASHR, CHECK_OP(op1 > inst->type, "bytecode attempted to execute ashr greater than bitwidth\n");
710
res = CLI_SRS(sop0, op1));
712
DEFINE_BINOP(OP_BC_AND, res = op0 & op1);
713
DEFINE_BINOP(OP_BC_OR, res = op0 | op1);
714
DEFINE_BINOP(OP_BC_XOR, res = op0 ^ op1);
716
DEFINE_SCASTOP(OP_BC_SEXT,
717
CHOOSE(READ1(sres, inst->u.cast.source); res = sres ? ~0ull : 0,
718
READ8(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask),
719
READ16(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask),
720
READ32(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask),
721
READ64(sres, inst->u.cast.source); res=sres=SIGNEXT(sres, inst->u.cast.mask)));
722
DEFINE_CASTOP(OP_BC_ZEXT,
723
CHOOSE(READ1(res, inst->u.cast.source),
724
READ8(res, inst->u.cast.source),
725
READ16(res, inst->u.cast.source),
726
READ32(res, inst->u.cast.source),
727
READ64(res, inst->u.cast.source)));
728
DEFINE_CASTOP(OP_BC_TRUNC,
729
CHOOSE(READ1(res, inst->u.cast.source),
730
READ8(res, inst->u.cast.source),
731
READ16(res, inst->u.cast.source),
732
READ32(res, inst->u.cast.source),
733
READ64(res, inst->u.cast.source)));
735
DEFINE_OP(OP_BC_BRANCH)
736
stop = jump(func, (values[inst->u.branch.condition]&1) ?
737
inst->u.branch.br_true : inst->u.branch.br_false,
738
&bb, &inst, &bb_inst);
742
stop = jump(func, inst->u.jump, &bb, &inst, &bb_inst);
745
DEFINE_OP_BC_RET_N(OP_BC_RET*5, uint8_t, READ1, WRITE8);
746
DEFINE_OP_BC_RET_N(OP_BC_RET*5+1, uint8_t, READ8, WRITE8);
747
DEFINE_OP_BC_RET_N(OP_BC_RET*5+2, uint16_t, READ16, WRITE16);
748
DEFINE_OP_BC_RET_N(OP_BC_RET*5+3, uint32_t, READ32, WRITE32);
749
DEFINE_OP_BC_RET_N(OP_BC_RET*5+4, uint64_t, READ64, WRITE64);
751
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5, uint8_t, (void), (void));
752
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+1, uint8_t, (void), (void));
753
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+2, uint8_t, (void), (void));
754
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+3, uint8_t, (void), (void));
755
DEFINE_OP_BC_RET_N(OP_BC_RET_VOID*5+4, uint8_t, (void), (void));
757
DEFINE_ICMPOP(OP_BC_ICMP_EQ, res = (op0 == op1));
758
DEFINE_ICMPOP(OP_BC_ICMP_NE, res = (op0 != op1));
759
DEFINE_ICMPOP(OP_BC_ICMP_UGT, res = (op0 > op1));
760
DEFINE_ICMPOP(OP_BC_ICMP_UGE, res = (op0 >= op1));
761
DEFINE_ICMPOP(OP_BC_ICMP_ULT, res = (op0 < op1));
762
DEFINE_ICMPOP(OP_BC_ICMP_ULE, res = (op0 <= op1));
763
DEFINE_ICMPOP(OP_BC_ICMP_SGT, res = (sop0 > sop1));
764
DEFINE_ICMPOP(OP_BC_ICMP_SGE, res = (sop0 >= sop1));
765
DEFINE_ICMPOP(OP_BC_ICMP_SLE, res = (sop0 <= sop1));
766
DEFINE_ICMPOP(OP_BC_ICMP_SLT, res = (sop0 < sop1));
771
READ1(t0, inst->u.three[0]);
772
READ1(t1, inst->u.three[1]);
773
READ1(t2, inst->u.three[2]);
774
WRITE8(inst->dest, t0 ? t1 : t2);
777
case OP_BC_SELECT*5+1:
780
READ1(t0, inst->u.three[0]);
781
READ8(t1, inst->u.three[1]);
782
READ8(t2, inst->u.three[2]);
783
WRITE8(inst->dest, t0 ? t1 : t2);
786
case OP_BC_SELECT*5+2:
790
READ1(t0, inst->u.three[0]);
791
READ16(t1, inst->u.three[1]);
792
READ16(t2, inst->u.three[2]);
793
WRITE16(inst->dest, t0 ? t1 : t2);
796
case OP_BC_SELECT*5+3:
800
READ1(t0, inst->u.three[0]);
801
READ32(t1, inst->u.three[1]);
802
READ32(t2, inst->u.three[2]);
803
WRITE32(inst->dest, t0 ? t1 : t2);
806
case OP_BC_SELECT*5+4:
810
READ1(t0, inst->u.three[0]);
811
READ64(t1, inst->u.three[1]);
812
READ64(t2, inst->u.three[2]);
813
WRITE64(inst->dest, t0 ? t1 : t2);
817
DEFINE_OP(OP_BC_CALL_API) {
818
const struct cli_apicall *api = &cli_apicalls[inst->u.ops.funcid];
821
CHECK_APIID(inst->u.ops.funcid);
822
TRACE_API(api->name, inst->dest, inst->type, stack_depth);
826
READ32(a, inst->u.ops.ops[0]);
827
READ32(b, inst->u.ops.ops[1]);
828
res32 = cli_apicalls0[api->idx](ctx, a, b);
829
WRITE32(inst->dest, res32);
835
unsigned arg2, arg1size;
836
READ32(arg2, inst->u.ops.ops[1]);
837
/* check that arg2 is size of arg1 */
839
for (i=0;i<sizeof(apisize_override)/sizeof(apisize_override[0]);i++) {
840
if (cli_apicalls1[api->idx] == apisize_override[i].api) {
841
arg1size = apisize_override[i].override_size;
845
READPOP(arg1, inst->u.ops.ops[0], arg1size);
846
res32 = cli_apicalls1[api->idx](ctx, arg1, arg2);
847
WRITE32(inst->dest, res32);
852
READ32(a, inst->u.ops.ops[0]);
853
res32 = cli_apicalls2[api->idx](ctx, a);
854
WRITE32(inst->dest, res32);
860
READ32(a, inst->u.ops.ops[0]);
861
resp = cli_apicalls3[api->idx](ctx, a);
862
res64 = ptr_register_glob(&ptrinfos, resp, a);
863
WRITE64(inst->dest, res64);
867
int32_t arg2, arg3, arg4, arg5;
869
READ32(arg2, inst->u.ops.ops[1]);
870
/* check that arg2 is size of arg1 */
871
READP(arg1, inst->u.ops.ops[0], arg2);
872
READ32(arg3, inst->u.ops.ops[2]);
873
READ32(arg4, inst->u.ops.ops[3]);
874
READ32(arg5, inst->u.ops.ops[4]);
875
res32 = cli_apicalls4[api->idx](ctx, arg1, arg2, arg3, arg4, arg5);
876
WRITE32(inst->dest, res32);
880
res32 = cli_apicalls5[api->idx](ctx);
881
WRITE32(inst->dest, res32);
887
READ32(arg1, inst->u.ops.ops[0]);
888
READ32(arg2, inst->u.ops.ops[1]);
889
resp = cli_apicalls6[api->idx](ctx, arg1, arg2);
890
res64 = ptr_register_glob(&ptrinfos, resp, arg2);
891
WRITE64(inst->dest, res64);
895
int32_t arg1,arg2,arg3;
896
READ32(arg1, inst->u.ops.ops[0]);
897
READ32(arg2, inst->u.ops.ops[1]);
898
READ32(arg3, inst->u.ops.ops[2]);
899
res32 = cli_apicalls7[api->idx](ctx, arg1, arg2, arg3);
900
WRITE32(inst->dest, res32);
907
READ32(arg2, inst->u.ops.ops[1]);
908
/* check that arg2 is size of arg1 */
909
READP(arg1, inst->u.ops.ops[0], arg2);
910
READ32(arg4, inst->u.ops.ops[3]);
911
READP(arg3, inst->u.ops.ops[2], arg4);
912
resp = cli_apicalls8[api->idx](ctx, arg1, arg2, arg3, arg4);
913
WRITE32(inst->dest, resp);
920
READ32(arg2, inst->u.ops.ops[1]);
921
/* check that arg2 is size of arg1 */
922
READP(arg1, inst->u.ops.ops[0], arg2);
923
READ32(arg3, inst->u.ops.ops[2]);
924
resp = cli_apicalls9[api->idx](ctx, arg1, arg2, arg3);
925
WRITE32(inst->dest, resp);
929
cli_warnmsg("bytecode: type %u apicalls not yet implemented!\n", api->kind);
935
DEFINE_OP(OP_BC_CALL_DIRECT)
936
CHECK_FUNCID(inst->u.ops.funcid);
937
func2 = &bc->funcs[inst->u.ops.funcid];
938
CHECK_EQ(func2->numArgs, inst->u.ops.numOps);
940
stack_entry = allocate_stack(&stack, stack_entry, func2, func, inst->dest,
946
values = stack_entry->values;
947
/* TODO: unregister on ret */
948
TRACE_EXEC(inst->u.ops.funcid, inst->dest, inst->type, stack_depth);
949
if (stack_depth > 10000) {
950
cli_warnmsg("bytecode: stack depth exceeded\n");
955
for (i=0;i<func2->numArgs;i++) {
956
switch (inst->u.ops.opsizes[i]) {
959
READOLD8(v, inst->u.ops.ops[i]);
960
CHECK_GT(func2->numBytes, j);
966
READOLD16(v, inst->u.ops.ops[i]);
968
CHECK_GT(func2->numBytes, j);
969
*(uint16_t*)&values[j] = v;
975
READOLD32(v, inst->u.ops.ops[i]);
977
CHECK_GT(func2->numBytes, j);
978
*(uint32_t*)&values[j] = v;
984
READOLD64(v, inst->u.ops.ops[i]);
986
CHECK_GT(func2->numBytes, j);
987
*(uint64_t*)&values[j] = v;
994
stackid = ptr_register_stack(&ptrinfos, values, 0, func->numBytes)>>32;
995
CHECK_GT(func->numBB, 0);
996
stop = jump(func, 0, &bb, &inst, &bb_inst);
1003
READ1(op, BINOP(0));
1004
WRITE8(BINOP(1), op);
1007
case OP_BC_COPY*5+1:
1010
READ8(op, BINOP(0));
1011
WRITE8(BINOP(1), op);
1014
case OP_BC_COPY*5+2:
1017
READ16(op, BINOP(0));
1018
WRITE16(BINOP(1), op);
1021
case OP_BC_COPY*5+3:
1024
READ32(op, BINOP(0));
1025
WRITE32(BINOP(1), op);
1028
case OP_BC_COPY*5+4:
1031
READ64(op, BINOP(0));
1032
WRITE64(BINOP(1), op);
1037
case OP_BC_LOAD*5+1:
1040
READPOP(ptr, inst->u.unaryop, 1);
1041
WRITE8(inst->dest, (*ptr));
1044
case OP_BC_LOAD*5+2:
1046
const union unaligned_16 *ptr;
1047
READPOP(ptr, inst->u.unaryop, 2);
1048
WRITE16(inst->dest, (ptr->una_u16));
1051
case OP_BC_LOAD*5+3:
1053
const union unaligned_32 *ptr;
1054
READPOP(ptr, inst->u.unaryop, 4);
1055
WRITE32(inst->dest, (ptr->una_u32));
1058
case OP_BC_LOAD*5+4:
1060
const union unaligned_64 *ptr;
1061
READPOP(ptr, inst->u.unaryop, 8);
1062
WRITE64(inst->dest, (ptr->una_u64));
1070
READP(ptr, BINOP(1), 1);
1075
case OP_BC_STORE*5+1:
1079
READP(ptr, BINOP(1), 1);
1084
case OP_BC_STORE*5+2:
1086
union unaligned_16 *ptr;
1088
READP(ptr, BINOP(1), 2);
1089
READ16(v, BINOP(0));
1093
case OP_BC_STORE*5+3:
1095
union unaligned_32 *ptr;
1097
READP(ptr, BINOP(1), 4);
1098
READ32(v, BINOP(0));
1102
case OP_BC_STORE*5+4:
1104
union unaligned_64 *ptr;
1106
READP(ptr, BINOP(1), 8);
1107
READ64(v, BINOP(0));
1111
DEFINE_OP(OP_BC_ISBIGENDIAN) {
1112
WRITE8(inst->dest, WORDS_BIGENDIAN);
1115
DEFINE_OP(OP_BC_GEPZ) {
1118
READ32(off, inst->u.three[2]);
1120
// negative values checking, valid for intermediate GEP calculations
1122
cli_dbgmsg("bytecode warning: found GEP with negative offset %d!\n", off);
1125
if (!(inst->interp_op%5)) {
1126
// how do negative offsets affect pointer intialization?
1127
WRITE64(inst->dest, ptr_compose(stackid,
1128
inst->u.three[1]+off));
1130
READ64(ptr, inst->u.three[1]);
1131
off += (ptr & 0x00000000ffffffffULL);
1132
iptr = (ptr & 0xffffffff00000000ULL) + (uint64_t)(off);
1133
WRITE64(inst->dest, ptr+off);
1137
DEFINE_OP(OP_BC_MEMCMP) {
1140
READ32(arg3, inst->u.three[2]);
1141
READPOP(arg1, inst->u.three[0], arg3);
1142
READPOP(arg2, inst->u.three[1], arg3);
1143
WRITE32(inst->dest, memcmp(arg1, arg2, arg3));
1146
DEFINE_OP(OP_BC_MEMCPY) {
1150
READ32(arg3, inst->u.three[2]);
1151
READPOP(arg1, inst->u.three[0], arg3);
1152
READPOP(arg2, inst->u.three[1], arg3);
1153
memcpy(arg1, arg2, (int32_t)arg3);
1156
DEFINE_OP(OP_BC_MEMMOVE) {
1160
READ64(arg3, inst->u.three[2]);
1161
READPOP(arg1, inst->u.three[0], arg3);
1162
READPOP(arg2, inst->u.three[1], arg3);
1163
memmove(arg1, arg2, (int32_t)arg3);
1166
DEFINE_OP(OP_BC_MEMSET) {
1171
READ64(arg3, inst->u.three[2]);
1172
READPOP(arg1, inst->u.three[0], arg3);
1173
READ32(arg2, inst->u.three[1]);
1174
memset(arg1, arg2, (int32_t)arg3);
1177
DEFINE_OP(OP_BC_BSWAP16) {
1179
READ16(arg1, inst->u.unaryop);
1180
WRITE16(inst->dest, cbswap16(arg1));
1183
DEFINE_OP(OP_BC_BSWAP32) {
1185
READ32(arg1, inst->u.unaryop);
1186
WRITE32(inst->dest, cbswap32(arg1));
1189
DEFINE_OP(OP_BC_BSWAP64) {
1191
READ64(arg1, inst->u.unaryop);
1192
WRITE64(inst->dest, cbswap64(arg1));
1195
DEFINE_OP(OP_BC_PTRDIFF32) {
1197
if (BINOP(0)&0x40000000)
1198
ptr1 = ptr_compose(stackid, BINOP(0)&0xbfffffff);
1200
READ64(ptr1, BINOP(0));
1201
if (BINOP(1)&0x40000000)
1202
ptr2 = ptr_compose(stackid, BINOP(1)&0xbfffffff);
1204
READ64(ptr2, BINOP(1));
1205
WRITE32(inst->dest, ptr_diff32(ptr1, ptr2));
1208
DEFINE_OP(OP_BC_PTRTOINT64) {
1210
if (inst->u.unaryop&0x40000000)
1211
ptr = ptr_compose(stackid, inst->u.unaryop&0xbfffffff);
1213
READ64(ptr, BINOP(0));
1214
WRITE64(inst->dest, ptr);
1217
DEFINE_OP(OP_BC_GEP1) {
1220
READ32(off, inst->u.three[2]);
1222
// negative values checking, valid for intermediate GEP calculations
1224
cli_dbgmsg("bytecode warning: GEP with negative offset %d!\n", off);
1226
if (inst->u.three[0] < 0) {
1227
cli_dbgmsg("bytecode warning: GEP with negative size %d!\n", inst->u.three[0]);
1230
if (!(inst->interp_op%5)) {
1231
// how do negative offsets affect pointer intialization?
1232
cli_dbgmsg("bytecode warning: untested case for GEP1\n");
1233
off *= inst->u.three[0];
1234
WRITE64(inst->dest, ptr_compose(stackid,
1235
inst->u.three[1]+off));
1237
READ64(ptr, inst->u.three[1]);
1238
off *= inst->u.three[0];
1239
off += (ptr & 0x00000000ffffffff);
1240
iptr = (ptr & 0xffffffff00000000) + (uint64_t)(off);
1241
WRITE64(inst->dest, iptr);
1245
/* TODO: implement OP_BC_GEP1, OP_BC_GEP2, OP_BC_GEPN */
1247
cli_errmsg("Opcode %u of type %u is not implemented yet!\n",
1248
inst->interp_op/5, inst->interp_op%5);
1255
CHECK_GT(bb->numInsts, bb_inst);
1241
1257
} while (stop == CL_SUCCESS);
1242
1258
if (cli_debug_flag) {
1243
gettimeofday(&tv1, NULL);
1244
tv1.tv_sec -= tv0.tv_sec;
1245
tv1.tv_usec -= tv0.tv_usec;
1246
cli_dbgmsg("intepreter bytecode run finished in %luus, after executing %u opcodes\n",
1247
tv1.tv_sec*1000000 + tv1.tv_usec, pc);
1259
gettimeofday(&tv1, NULL);
1260
tv1.tv_sec -= tv0.tv_sec;
1261
tv1.tv_usec -= tv0.tv_usec;
1262
cli_dbgmsg("intepreter bytecode run finished in %luus, after executing %u opcodes\n",
1263
tv1.tv_sec*1000000 + tv1.tv_usec, pc);
1249
1265
if (stop == CL_EBYTECODE) {
1250
cli_event_error_str(ctx->bc_events, "interpreter finished with error\n");
1251
cli_dbgmsg("intepreter finished with error\n");
1266
cli_event_error_str(ctx->bc_events, "interpreter finished with error\n");
1267
cli_dbgmsg("intepreter finished with error\n");
1254
1270
cli_stack_destroy(&stack);