Add overflow and underflow checking for floats
This commit is contained in:
parent
84648fbd88
commit
93174c8e68
|
@ -38,8 +38,7 @@ There are still several open areas, but most targets have been reached. The cur
|
|||
|
||||
### Runtime
|
||||
|
||||
* No INF and NaN support for floats
|
||||
* Underflow in float multiply and divide not checked
|
||||
* No NaN support for floats
|
||||
* Basic zero page variables not restored on stop/restore
|
||||
|
||||
### Optimizing
|
||||
|
|
107
include/crt.c
107
include/crt.c
|
@ -2474,6 +2474,22 @@ W1:
|
|||
|
||||
__asm faddsub
|
||||
{
|
||||
lda #$ff
|
||||
cmp tmp + 4
|
||||
beq INF
|
||||
cmp tmp + 5
|
||||
bne nINF
|
||||
INF:
|
||||
lda accu + 3
|
||||
ora #$7f
|
||||
sta accu + 3
|
||||
lda #$80
|
||||
sta accu + 2
|
||||
lda #$00
|
||||
sta accu + 0
|
||||
sta accu + 1
|
||||
rts
|
||||
nINF:
|
||||
sec
|
||||
lda tmp + 4
|
||||
sbc tmp + 5
|
||||
|
@ -2542,6 +2558,8 @@ fas_aligned:
|
|||
inc tmp + 4
|
||||
fas_done:
|
||||
lda tmp + 4
|
||||
cmp #$ff
|
||||
beq INF
|
||||
lsr
|
||||
ora accu + 3
|
||||
sta accu + 3
|
||||
|
@ -2677,6 +2695,17 @@ W1:
|
|||
sta accu + 3
|
||||
rts
|
||||
W2:
|
||||
lda accu + 3
|
||||
eor tmp + 3
|
||||
and #$80
|
||||
sta accu + 3
|
||||
|
||||
lda #$ff
|
||||
cmp tmp + 4
|
||||
beq INF
|
||||
cmp tmp + 5
|
||||
beq INF
|
||||
|
||||
lda #0
|
||||
sta tmp + 6
|
||||
sta tmp + 7
|
||||
|
@ -2707,16 +2736,28 @@ W5:
|
|||
W3: and #$7f
|
||||
sta tmp + 8
|
||||
|
||||
lda accu + 3
|
||||
eor tmp + 3
|
||||
and #$80
|
||||
sta accu + 3
|
||||
|
||||
lda tmp + 4
|
||||
sbc #$7e
|
||||
|
||||
clc
|
||||
adc tmp + 5
|
||||
bcc W7
|
||||
|
||||
sbc #$7f
|
||||
bcs INF
|
||||
cmp #$ff
|
||||
bne W8
|
||||
INF:
|
||||
lda accu + 3
|
||||
ora #$7f
|
||||
sta accu + 3
|
||||
lda #$80
|
||||
sta accu + 2
|
||||
lda #$00
|
||||
sta accu + 0
|
||||
sta accu + 1
|
||||
rts
|
||||
W7:
|
||||
sbc #$7e
|
||||
bcc ZERO
|
||||
W8:
|
||||
lsr
|
||||
ora accu + 3
|
||||
sta accu + 3
|
||||
|
@ -2729,6 +2770,13 @@ W3: and #$7f
|
|||
lda tmp + 6
|
||||
sta accu
|
||||
rts
|
||||
ZERO:
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
sta accu + 2
|
||||
sta accu + 3
|
||||
rts
|
||||
}
|
||||
|
||||
__asm inp_binop_mul_f32
|
||||
|
@ -2754,6 +2802,12 @@ W1:
|
|||
and #$80
|
||||
sta accu + 3
|
||||
|
||||
lda tmp + 5
|
||||
beq INF
|
||||
lda tmp + 4
|
||||
cmp #$ff
|
||||
beq INF
|
||||
|
||||
lda #0
|
||||
sta tmp + 6
|
||||
sta tmp + 7
|
||||
|
@ -2804,12 +2858,29 @@ W4:
|
|||
and #$7f
|
||||
sta tmp + 8
|
||||
|
||||
lda tmp + 5
|
||||
eor #$7f
|
||||
adc tmp + 4
|
||||
sec
|
||||
sbc #1
|
||||
lda tmp + 4
|
||||
sbc tmp + 5
|
||||
bcc W5
|
||||
|
||||
clc
|
||||
adc #$7f
|
||||
bcs INF
|
||||
cmp #$ff
|
||||
bne W6
|
||||
INF:
|
||||
lda accu + 3
|
||||
ora #$7f
|
||||
sta accu + 3
|
||||
lda #$80
|
||||
sta accu + 2
|
||||
lda #$00
|
||||
sta accu + 1
|
||||
sta accu + 0
|
||||
rts
|
||||
W5:
|
||||
adc #$7f
|
||||
bcc ZERO
|
||||
W6:
|
||||
lsr
|
||||
ora accu + 3
|
||||
sta accu + 3
|
||||
|
@ -2822,6 +2893,16 @@ W4:
|
|||
lda tmp + 6
|
||||
sta accu
|
||||
rts
|
||||
|
||||
ZERO:
|
||||
lda #$00
|
||||
sta accu + 3
|
||||
sta accu + 2
|
||||
sta accu + 1
|
||||
sta accu + 0
|
||||
rts
|
||||
|
||||
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_BINOP_MUL_F32, inp_binop_mul_f32)
|
||||
|
|
|
@ -199,3 +199,37 @@ float sqrt(float f)
|
|||
}
|
||||
|
||||
|
||||
bool isinf(float f)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda #$00
|
||||
sta accu + 1
|
||||
asl f + 2
|
||||
lda f + 3
|
||||
rol
|
||||
eor #$ff
|
||||
beq W1
|
||||
lda #$01
|
||||
W1:
|
||||
eor #$01
|
||||
sta accu
|
||||
}
|
||||
}
|
||||
|
||||
bool isfinite(float f)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda #$00
|
||||
sta accu + 1
|
||||
asl f + 2
|
||||
lda f + 3
|
||||
rol
|
||||
eor #$ff
|
||||
beq W1
|
||||
lda #$01
|
||||
W1:
|
||||
sta accu
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ float log10(float f);
|
|||
float pow(float p, float q);
|
||||
float sqrt(float f);
|
||||
|
||||
bool isinf(float f);
|
||||
bool isfinite(float f);
|
||||
|
||||
#pragma intrinsic(fabs)
|
||||
#pragma intrinsic(floor)
|
||||
#pragma intrinsic(ceil)
|
||||
|
|
|
@ -259,6 +259,14 @@ int nformf(const sinfo * si, char * str, float f, char type)
|
|||
else if (si->sign)
|
||||
sp[d++] = '+';
|
||||
|
||||
if (isinf(f))
|
||||
{
|
||||
sp[d++] = 'I';
|
||||
sp[d++] = 'N';
|
||||
sp[d++] = 'F';
|
||||
}
|
||||
else
|
||||
{
|
||||
int exp = 0;
|
||||
|
||||
char fdigits = si->precision != 255 ? si->precision : 6;
|
||||
|
@ -359,6 +367,7 @@ int nformf(const sinfo * si, char * str, float f, char type)
|
|||
sp[d++] = exp / 10 + '0';
|
||||
sp[d++] = exp % 10 + '0';
|
||||
}
|
||||
}
|
||||
|
||||
if (d < si->width)
|
||||
{
|
||||
|
|
|
@ -707,6 +707,59 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
|||
nexp->mDecValue = ndec;
|
||||
exp = nexp;
|
||||
}
|
||||
else if (exp->mType == EX_CONSTANT && exp->mDecType != dtype)
|
||||
{
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
nexp->mDecType = dtype;
|
||||
|
||||
if (dtype->mType == DT_TYPE_INTEGER || dtype->mType == DT_TYPE_ENUM || dtype->mType == DT_TYPE_BOOL)
|
||||
{
|
||||
Declaration* ndec = new Declaration(exp->mDecValue->mLocation, DT_CONST_INTEGER);
|
||||
ndec->mBase = dtype;
|
||||
ndec->mSize = dtype->mSize;
|
||||
|
||||
if (exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||
ndec->mInteger = exp->mDecValue->mInteger;
|
||||
else if (exp->mDecValue->mType == DT_CONST_FLOAT)
|
||||
ndec->mInteger = int64(exp->mDecValue->mNumber);
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Illegal integer constant initializer");
|
||||
|
||||
nexp->mDecValue = ndec;
|
||||
}
|
||||
else if (dtype->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
Declaration* ndec = new Declaration(exp->mDecValue->mLocation, DT_CONST_FLOAT);
|
||||
ndec->mBase = dtype;
|
||||
ndec->mSize = dtype->mSize;
|
||||
|
||||
if (exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||
ndec->mNumber = double(exp->mDecValue->mInteger);
|
||||
else if (exp->mDecValue->mType == DT_CONST_FLOAT)
|
||||
ndec->mNumber = exp->mDecValue->mNumber;
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Illegal float constant initializer");
|
||||
|
||||
nexp->mDecValue = ndec;
|
||||
}
|
||||
else if (dtype->mType == DT_TYPE_POINTER)
|
||||
{
|
||||
if (exp->mDecValue->mType == DT_CONST_ADDRESS)
|
||||
;
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Illegal pointer constant initializer");
|
||||
|
||||
nexp = exp;
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Illegal constant initializer");
|
||||
nexp = exp;
|
||||
}
|
||||
|
||||
exp = nexp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return exp;
|
||||
|
|
Loading…
Reference in New Issue