scf_list_t* l2;
scf_list_t* cond_prev = scf_list_tail(d->_3ac_list_head);
- for (l = scf_list_next(start_prev); l != &jmp_end->list; l = scf_list_next(l)) {
- c = scf_list_data(l, scf_3ac_code_t, list);
+ int jmp_op = -1;
+ if (jmp_end) {
+ for (l = scf_list_next(start_prev); l != &jmp_end->list; l = scf_list_next(l)) {
+ c = scf_list_data(l, scf_3ac_code_t, list);
- c2 = scf_3ac_code_clone(c);
- if (!c2)
- return -ENOMEM;
+ c2 = scf_3ac_code_clone(c);
+ if (!c2)
+ return -ENOMEM;
- scf_list_add_tail(d->_3ac_list_head, &c2->list);
- }
+ scf_list_add_tail(d->_3ac_list_head, &c2->list);
+ }
- for (l = scf_list_next(cond_prev); l != scf_list_sentinel(d->_3ac_list_head); l = scf_list_next(l)) {
- c = scf_list_data(l, scf_3ac_code_t, list);
+ for (l = scf_list_next(cond_prev); l != scf_list_sentinel(d->_3ac_list_head); l = scf_list_next(l)) {
+ c = scf_list_data(l, scf_3ac_code_t, list);
- if (!scf_type_is_jmp(c->op->type))
- continue;
+ if (!scf_type_is_jmp(c->op->type))
+ continue;
- for (l2 = scf_list_next(cond_prev); l2 != scf_list_sentinel(d->_3ac_list_head); l2 = scf_list_next(l2)) {
- c2 = scf_list_data(l2, scf_3ac_code_t, list);
+ for (l2 = scf_list_next(cond_prev); l2 != scf_list_sentinel(d->_3ac_list_head); l2 = scf_list_next(l2)) {
+ c2 = scf_list_data(l2, scf_3ac_code_t, list);
- dst = c->dsts->data[0];
+ dst = c->dsts->data[0];
- if (dst->code == c2->origin) {
- dst->code = c2;
- break;
+ if (dst->code == c2->origin) {
+ dst->code = c2;
+ break;
+ }
}
+ assert(l2 != scf_list_sentinel(d->_3ac_list_head));
+
+ if (scf_vector_add(d->branch_ops->_breaks, c) < 0)
+ return -1;
}
- assert(l2 != scf_list_sentinel(d->_3ac_list_head));
- if (scf_vector_add(d->branch_ops->_breaks, c) < 0)
- return -1;
- }
+ switch (jmp_end->op->type) {
- int jmp_op = -1;
- switch (jmp_end->op->type) {
+ case SCF_OP_3AC_JNZ:
+ jmp_op = SCF_OP_3AC_JZ;
+ break;
+ case SCF_OP_3AC_JZ:
+ jmp_op = SCF_OP_3AC_JNZ;
+ break;
+ case SCF_OP_3AC_JLE:
+ jmp_op = SCF_OP_3AC_JGT;
+ break;
+ case SCF_OP_3AC_JLT:
+ jmp_op = SCF_OP_3AC_JGE;
+ break;
+ case SCF_OP_3AC_JGE:
+ jmp_op = SCF_OP_3AC_JLT;
+ break;
+ case SCF_OP_3AC_JGT:
+ jmp_op = SCF_OP_3AC_JLE;
+ break;
- case SCF_OP_3AC_JNZ:
- jmp_op = SCF_OP_3AC_JZ;
- break;
- case SCF_OP_3AC_JZ:
- jmp_op = SCF_OP_3AC_JNZ;
- break;
- case SCF_OP_3AC_JLE:
- jmp_op = SCF_OP_3AC_JGT;
- break;
- case SCF_OP_3AC_JLT:
- jmp_op = SCF_OP_3AC_JGE;
- break;
- case SCF_OP_3AC_JGE:
- jmp_op = SCF_OP_3AC_JLT;
- break;
- case SCF_OP_3AC_JGT:
- jmp_op = SCF_OP_3AC_JLE;
- break;
+ case SCF_OP_3AC_JA:
+ jmp_op = SCF_OP_3AC_JBE;
+ break;
+ case SCF_OP_3AC_JAE:
+ jmp_op = SCF_OP_3AC_JB;
+ break;
- case SCF_OP_3AC_JA:
- jmp_op = SCF_OP_3AC_JBE;
- break;
- case SCF_OP_3AC_JAE:
- jmp_op = SCF_OP_3AC_JB;
- break;
+ case SCF_OP_3AC_JB:
+ jmp_op = SCF_OP_3AC_JAE;
+ break;
+ case SCF_OP_3AC_JBE:
+ jmp_op = SCF_OP_3AC_JA;
+ break;
- case SCF_OP_3AC_JB:
- jmp_op = SCF_OP_3AC_JAE;
- break;
- case SCF_OP_3AC_JBE:
- jmp_op = SCF_OP_3AC_JA;
- break;
+ default:
+ scf_loge("NOT support jmp op %d\n", jmp_end->op->type);
+ return -1;
+ break;
+ };
+ }
- default:
- jmp_op = -1;
- break;
- };
+ scf_3ac_code_t* loop = NULL;
+ scf_3ac_code_t* start = NULL;
+
+ if (jmp_end) {
+ // add loop when true
+ loop = scf_3ac_jmp_code(jmp_op, NULL, NULL);
+ scf_list_add_tail(d->_3ac_list_head, &loop->list);
- // add loop when true
- scf_3ac_code_t* loop = scf_3ac_jmp_code(jmp_op, NULL, NULL);
- scf_list_add_tail(d->_3ac_list_head, &loop->list);
+ // should get the real start here,
+ start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list);
+ } else {
+ loop = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
+ scf_list_add_tail(d->_3ac_list_head, &loop->list);
- // should get the real start here,
- scf_3ac_code_t* start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list);
+ start = scf_list_data(scf_list_next(start_prev), scf_3ac_code_t, list);
+ }
dst = loop->dsts->data[0];
dst->code = start;
assert(4 == nb_nodes);
scf_handler_data_t* d = data;
- int ret = 0;
+ scf_variable_t* r;
+ scf_node_t* cond;
+ int i;
- if (nodes[0]) {
- ret = _scf_op_semantic_node(ast, nodes[0], d);
- if (ret < 0) {
- scf_loge("\n");
- return ret;
- }
- }
+ for (i = 0; i < nb_nodes; i++) {
+ if (!nodes[i])
+ continue;
- scf_node_t* cond = nodes[1];
- if (cond) {
- ret = _scf_op_semantic_node(ast, cond, d);
+ int ret = _scf_op_semantic_node(ast, nodes[i], d);
if (ret < 0) {
scf_loge("\n");
return ret;
}
- if (cond->nb_nodes > 0) { // the final expr is real cond expr
- scf_variable_t* r = _scf_operand_get(cond->nodes[cond->nb_nodes - 1]);
+ if (1 == i) {
+ cond = nodes[i];
+
+ if (cond->nb_nodes <= 0)
+ continue;
+
+ // the final expr is real cond expr
+ r = _scf_operand_get(cond->nodes[cond->nb_nodes - 1]);
if (!r || !scf_variable_integer(r)) {
scf_loge("\n");
}
}
- int i;
- for (i = 2; i < nb_nodes; i++) {
- if (!nodes[i])
- continue;
-
- ret = _scf_op_semantic_node(ast, nodes[i], d);
- if (ret < 0) {
- scf_loge("\n");
- return ret;
- }
- }
-
return 0;
}