mirror of https://github.com/arendst/Tasmota.git
Fix Berry compound assignment
This commit is contained in:
parent
8b56aa6943
commit
a08b54b295
|
@ -335,12 +335,15 @@ static void free_suffix(bfuncinfo *finfo, bexpdesc *e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst)
|
static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst, bbool no_reg_reuse)
|
||||||
{
|
{
|
||||||
int cand_dst = dst; /* candidate for new dst */
|
int cand_dst = dst; /* candidate for new dst */
|
||||||
int nlocal = be_list_count(finfo->local);
|
int nlocal = be_list_count(finfo->local);
|
||||||
int reg1 = (e1->v.ss.tt == ETREG) ? e1->v.ss.obj : -1; /* check if obj is ETREG or -1 */
|
int reg1 = (e1->v.ss.tt == ETREG) ? e1->v.ss.obj : -1; /* check if obj is ETREG or -1 */
|
||||||
int reg2 = (!isK(e1->v.ss.idx) && e1->v.ss.idx >= nlocal) ? e1->v.ss.idx : -1; /* check if idx is ETREG or -1 */
|
int reg2 = (!isK(e1->v.ss.idx) && e1->v.ss.idx >= nlocal) ? e1->v.ss.idx : -1; /* check if idx is ETREG or -1 */
|
||||||
|
if (no_reg_reuse) { /* if no_reg_reuse flag, then don't reuse any register, this is useful for compound assignments */
|
||||||
|
reg1 = reg2 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (reg1 >= 0 && reg2 >= 0) {
|
if (reg1 >= 0 && reg2 >= 0) {
|
||||||
/* both are ETREG, we keep the lowest and discard the other */
|
/* both are ETREG, we keep the lowest and discard the other */
|
||||||
|
@ -364,9 +367,9 @@ static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst)
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst)
|
static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst, bbool no_reg_reuse)
|
||||||
{
|
{
|
||||||
dst = suffix_destreg(finfo, e, dst);
|
dst = suffix_destreg(finfo, e, dst, no_reg_reuse);
|
||||||
if (dst > finfo->freereg) {
|
if (dst > finfo->freereg) {
|
||||||
dst = finfo->freereg;
|
dst = finfo->freereg;
|
||||||
}
|
}
|
||||||
|
@ -400,6 +403,7 @@ static bbool constint(bfuncinfo *finfo, bint i)
|
||||||
/* At exit, If dst is `freereg`, the register is allocated */
|
/* At exit, If dst is `freereg`, the register is allocated */
|
||||||
static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
|
static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
|
||||||
{
|
{
|
||||||
|
bbool no_reg_reuse = (dst >= 0); /* if dst reg is explicitly specified, do not optimize register allocation */
|
||||||
if (dst < 0) { /* if unspecified, allocate a new register if needed */
|
if (dst < 0) { /* if unspecified, allocate a new register if needed */
|
||||||
dst = finfo->freereg;
|
dst = finfo->freereg;
|
||||||
}
|
}
|
||||||
|
@ -434,10 +438,10 @@ static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
|
||||||
codeABx(finfo, OP_GETUPV, dst, e->v.idx);
|
codeABx(finfo, OP_GETUPV, dst, e->v.idx);
|
||||||
break;
|
break;
|
||||||
case ETMEMBER:
|
case ETMEMBER:
|
||||||
dst = code_suffix(finfo, OP_GETMBR, e, dst);
|
dst = code_suffix(finfo, OP_GETMBR, e, dst, no_reg_reuse);
|
||||||
break;
|
break;
|
||||||
case ETINDEX:
|
case ETINDEX:
|
||||||
dst = code_suffix(finfo, OP_GETIDX, e, dst);
|
dst = code_suffix(finfo, OP_GETIDX, e, dst, no_reg_reuse);
|
||||||
break;
|
break;
|
||||||
case ETLOCAL: case ETREG: case ETCONST:
|
case ETLOCAL: case ETREG: case ETCONST:
|
||||||
return e->v.idx;
|
return e->v.idx;
|
||||||
|
@ -479,6 +483,7 @@ static int exp2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
|
||||||
/* Returns the destination register, guaranteed to be ETREG */
|
/* Returns the destination register, guaranteed to be ETREG */
|
||||||
static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst)
|
static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst)
|
||||||
{
|
{
|
||||||
|
if (dst < 0) { dst = finfo->freereg; }
|
||||||
int cand_dst = dst;
|
int cand_dst = dst;
|
||||||
int con1 = e1->type == ETREG, con2 = e2->type == ETREG;
|
int con1 = e1->type == ETREG, con2 = e2->type == ETREG;
|
||||||
|
|
||||||
|
@ -506,7 +511,6 @@ static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst)
|
||||||
/* On exit, e1 is guaranteed to be ETREG, which may have been allocated */
|
/* On exit, e1 is guaranteed to be ETREG, which may have been allocated */
|
||||||
static void binaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e1, bexpdesc *e2, int dst)
|
static void binaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e1, bexpdesc *e2, int dst)
|
||||||
{
|
{
|
||||||
if (dst < 0) { dst = finfo->freereg; }
|
|
||||||
int src1 = exp2reg(finfo, e1, dst); /* potentially force the target for src1 reg */
|
int src1 = exp2reg(finfo, e1, dst); /* potentially force the target for src1 reg */
|
||||||
int src2 = exp2anyreg(finfo, e2);
|
int src2 = exp2anyreg(finfo, e2);
|
||||||
dst = codedestreg(finfo, e1, e2, dst);
|
dst = codedestreg(finfo, e1, e2, dst);
|
||||||
|
@ -720,7 +724,7 @@ int be_code_getmethod(bfuncinfo *finfo, bexpdesc *e)
|
||||||
{
|
{
|
||||||
int dst = finfo->freereg;
|
int dst = finfo->freereg;
|
||||||
be_assert(e->type == ETMEMBER);
|
be_assert(e->type == ETMEMBER);
|
||||||
dst = code_suffix(finfo, OP_GETMET, e, dst);
|
dst = code_suffix(finfo, OP_GETMET, e, dst, bfalse);
|
||||||
/* method [object] args */
|
/* method [object] args */
|
||||||
be_code_allocregs(finfo, dst == finfo->freereg ? 2 : 1);
|
be_code_allocregs(finfo, dst == finfo->freereg ? 2 : 1);
|
||||||
return dst;
|
return dst;
|
||||||
|
|
Loading…
Reference in New Issue