Merge branch 'atari7800' of github.com:karrika/cc65 into atari7800

This commit is contained in:
Karri Kaksonen 2022-03-07 08:49:29 +02:00
commit 21c093476f
14 changed files with 294 additions and 67 deletions

View File

@ -29,7 +29,7 @@ MEMORY {
EXT: file = "", define = yes, start = $9000, size = $1000;
IO: file = "", define = yes, start = $A000, size = $1000;
RAE1: file = "", define = yes, start = $B000, size = $1000;
BASROM: file = "", define = yes, start = $C000, size = $1000;
BASROM: file = "", define = yes, start = $C000, size = $2000;
RAE2: file = "", define = yes, start = $E000, size = $1000;
TOP: file = "", define = yes, start = $F000, size = $1000;
}

View File

@ -29,7 +29,7 @@ MEMORY {
EXT: file = "", define = yes, start = $9000, size = $1000;
IO: file = "", define = yes, start = $A000, size = $1000;
RAE1: file = "", define = yes, start = $B000, size = $1000;
BASROM: file = "", define = yes, start = $C000, size = $1000;
BASROM: file = "", define = yes, start = $C000, size = $2000;
RAE2: file = "", define = yes, start = $E000, size = $1000;
TOP: file = "", define = yes, start = $F000, size = $1000;
}

View File

@ -29,7 +29,7 @@ MEMORY {
EXT: file = "", define = yes, start = $9000, size = $1000;
IO: file = "", define = yes, start = $A000, size = $1000;
RAE1: file = "", define = yes, start = $B000, size = $1000;
BASROM: file = "", define = yes, start = $C000, size = $1000;
BASROM: file = "", define = yes, start = $C000, size = $2000;
RAE2: file = "", define = yes, start = $E000, size = $1000;
TOP: file = "", define = yes, start = $F000, size = $1000;
}

View File

@ -52,24 +52,25 @@
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_RED 0x01
#define COLOR_PINK 0x02
#define COLOR_LIGHTGREY 0x03
#define COLOR_GREY 0x04
#define COLOR_DARKGREY 0x05
#define COLOR_BROWN 0x06
#define COLOR_PEACH 0x07
#define COLOR_YELLOW 0x08
#define COLOR_LIGHTGREEN 0x09
#define COLOR_GREEN 0x0A
#define COLOR_DARKBROWN 0x0B
#define COLOR_TRANSPARENT 0x00
#define COLOR_BLACK 0x01
#define COLOR_RED 0x02
#define COLOR_PINK 0x03
#define COLOR_LIGHTGREY 0x04
#define COLOR_GREY 0x05
#define COLOR_DARKGREY 0x06
#define COLOR_BROWN 0x07
#define COLOR_PEACH 0x08
#define COLOR_YELLOW 0x09
#define COLOR_LIGHTGREEN 0x0A
#define COLOR_GREEN 0x0B
#define COLOR_VIOLET 0x0C
#define COLOR_BLUE 0x0D
#define COLOR_LIGHTBLUE 0x0E
#define COLOR_WHITE 0x0F
/* TGI color defines (default palette) */
#define TGI_COLOR_TRANSPARENT COLOR_TRANSPARENT
#define TGI_COLOR_BLACK COLOR_BLACK
#define TGI_COLOR_RED COLOR_RED
#define TGI_COLOR_PINK COLOR_PINK
@ -81,7 +82,6 @@
#define TGI_COLOR_YELLOW COLOR_YELLOW
#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN
#define TGI_COLOR_GREEN COLOR_GREEN
#define TGI_COLOR_DARKBROWN COLOR_DARKBROWN
#define TGI_COLOR_VIOLET COLOR_VIOLET
#define TGI_COLOR_BLUE COLOR_BLUE
#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE

View File

@ -113,7 +113,8 @@ text_bitmap: .res 8*(1+20+1)+1
.rodata
DEFPALETTE: .byte >$011
DEFPALETTE: .byte >$223
.byte >$011
.byte >$34d
.byte >$9af
.byte >$9b8
@ -124,11 +125,11 @@ DEFPALETTE: .byte >$011
.byte >$d5f
.byte >$c53
.byte >$822
.byte >$223
.byte >$484
.byte >$8e5
.byte >$cf5
.byte >$fff
.byte <$223
.byte <$011
.byte <$34d
.byte <$9af
@ -140,7 +141,6 @@ DEFPALETTE: .byte >$011
.byte <$d5f
.byte <$c53
.byte <$822
.byte <$223
.byte <$484
.byte <$8e5
.byte <$cf5
@ -162,6 +162,7 @@ INSTALL:
lda #1
sta TEXTMAGX
sta TEXTMAGY
sta DRAWINDEX
stz BGINDEX
stz DRAWPAGE
stz SWAPREQUEST
@ -418,7 +419,7 @@ cls_sprite:
.word 0
.word $a000 ; 160
.word $6600 ; 102
.byte $00
.byte $11
.code
CLEAR: lda #<cls_sprite
@ -844,11 +845,6 @@ OUTTEXT:
lda TEXTMAGY
sta text_sy+1
lda BGINDEX
beq @L1 ; Choose opaque black sprite?
lda #$04 ; No, choose normal sprite
@L1:
sta text_sprite
lda DRAWINDEX ; Set color
asl
asl
@ -956,7 +952,7 @@ OUTTEXT:
text_coll:
.byte 0
text_sprite:
.byte $00,$90,$20
.byte $04,$90,$20
.addr 0, text_bitmap
text_x:
.word 0

View File

@ -4,5 +4,5 @@
.include "tgi-kernel.inc"
.export tgi_color_black:zp = $00
.export tgi_color_black:zp = $01
.export tgi_color_white:zp = $0F

View File

@ -309,10 +309,10 @@ unsigned OptCmp1 (CodeSeg* S)
/* Insert the ora instead */
X = NewCodeEntry (OP65_ORA, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
CS_InsertEntry (S, X, I);
CS_InsertEntry (S, X, I+3);
/* Remove all other instructions */
CS_DelEntries (S, I+1, 3);
CS_DelEntries (S, I, 3);
/* Remember, we had changes */
++Changes;

View File

@ -216,8 +216,11 @@ void LimitExprValue (ExprDesc* Expr)
break;
case T_LONG:
Expr->IVal = (int32_t)Expr->IVal;
break;
case T_ULONG:
/* No need to do anything */
Expr->IVal = (uint32_t)Expr->IVal;
break;
case T_SCHAR:
@ -2584,12 +2587,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
CmpSigned = 0;
flags |= CF_UNSIGNED;
}
} else {
unsigned rtype = TypeOf (Expr2.Type) | (flags & CF_CONST);
if (CmpSigned) {
ltype &= ~CF_UNSIGNED;
rtype &= ~CF_UNSIGNED;
}
flags |= g_typeadjust (ltype, rtype);
}

View File

@ -64,11 +64,11 @@ void ShiftExpr (struct ExprDesc* Expr)
CodeMark Mark1;
CodeMark Mark2;
token_t Tok; /* The operator token */
const Type* EffType; /* Effective lhs type */
const Type* ResultType; /* Type of the result */
unsigned ExprBits; /* Bits of the lhs operand */
unsigned GenFlags; /* Generator flags */
unsigned ltype;
int lconst; /* Operand is a constant */
int rconst; /* Operand is a constant */
@ -92,7 +92,7 @@ void ShiftExpr (struct ExprDesc* Expr)
NextToken ();
/* Get the type of the result */
ResultType = EffType = IntPromotion (Expr->Type);
ResultType = IntPromotion (Expr->Type);
/* Prepare the code generator flags */
GenFlags = TypeOf (ResultType);
@ -103,7 +103,8 @@ void ShiftExpr (struct ExprDesc* Expr)
/* Get the lhs on stack */
GetCodePos (&Mark1);
ltype = TypeOf (Expr->Type);
if (ED_IsConstAbs (Expr)) {
lconst = ED_IsConstAbs (Expr);
if (lconst) {
/* Constant value */
GetCodePos (&Mark2);
g_push (ltype | CF_CONST, Expr->IVal);
@ -115,7 +116,7 @@ void ShiftExpr (struct ExprDesc* Expr)
}
/* Get the right hand side */
ExprWithCheck (hie8, &Expr2);
MarkedExprWithCheck (hie8, &Expr2);
/* Check the type of the rhs */
if (!IsClassInt (Expr2.Type)) {
@ -124,7 +125,7 @@ void ShiftExpr (struct ExprDesc* Expr)
}
/* Check for a constant right side expression */
rconst = ED_IsConstAbs (&Expr2);
rconst = ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2);
if (!rconst) {
/* Not constant, load into the primary */
@ -154,31 +155,32 @@ void ShiftExpr (struct ExprDesc* Expr)
}
/* If the shift count is zero, nothing happens */
if (Expr2.IVal == 0) {
/* If the shift count is zero, nothing happens. If the left hand
** side is a constant, the result is constant.
*/
if (Expr2.IVal == 0 || lconst) {
/* Result is already in Expr, remove the generated code */
RemoveCode (&Mark1);
/* Set the type */
Expr->Type = ResultType;
/* Done */
goto Next;
}
if (lconst) {
/* If the left hand side is a constant, the result is constant */
if (ED_IsConstAbs (Expr)) {
/* Evaluate the result */
switch (Tok) {
case TOK_SHL: Expr->IVal <<= Expr2.IVal; break;
case TOK_SHR: Expr->IVal >>= Expr2.IVal; break;
default: /* Shutup gcc */ break;
}
/* Evaluate the result */
switch (Tok) {
case TOK_SHL: Expr->IVal <<= Expr2.IVal; break;
case TOK_SHR: Expr->IVal >>= Expr2.IVal; break;
default: /* Shutup gcc */ break;
/* Limit the calculated value to the range of its type */
LimitExprValue (Expr);
}
/* Both operands are constant, remove the generated code */
/* Result is already got, remove the generated code */
RemoveCode (&Mark1);
/* Done */
goto Next;
continue;
}
/* If we're shifting an integer or unsigned to the right, the lhs
@ -188,13 +190,12 @@ void ShiftExpr (struct ExprDesc* Expr)
** shift count is zero, we're done.
*/
if (Tok == TOK_SHR &&
IsTypeInt (Expr->Type) &&
IsClassInt (Expr->Type) &&
SizeOf (Expr->Type) == SIZEOF_INT &&
ED_IsLVal (Expr) &&
ED_IsLocQuasiConst (Expr) &&
Expr2.IVal >= 8) {
const Type* OldType;
/* Increase the address by one and decrease the shift count */
++Expr->IVal;
Expr2.IVal -= 8;
@ -202,7 +203,6 @@ void ShiftExpr (struct ExprDesc* Expr)
/* Replace the type of the expression temporarily by the
** corresponding char type.
*/
OldType = Expr->Type;
if (IsSignUnsigned (Expr->Type)) {
Expr->Type = type_uchar;
} else {
@ -215,9 +215,6 @@ void ShiftExpr (struct ExprDesc* Expr)
/* Generate again code for the load, this time with the new type */
LoadExpr (CF_NONE, Expr);
/* Reset the type */
Expr->Type = OldType;
/* If the shift count is now zero, we're done */
if (Expr2.IVal == 0) {
/* Be sure to mark the value as in the primary */
@ -238,7 +235,6 @@ MakeRVal:
/* We have an rvalue in the primary now */
ED_FinalizeRValLoad (Expr);
Next:
/* Set the type of the result */
Expr->Type = ResultType;
}

View File

@ -48,7 +48,7 @@ define LISTING_template
$(WORKDIR)/$1.bin: $1.s $(ISEQUAL)
$(if $(QUIET),echo asm/$1.bin)
# compile without generating listing
# compile without generating listing
$(CA65) -t none -o $$(@:.bin=.o) $$<
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib
@ -59,13 +59,13 @@ endif
$(CA65) -t none -l $$(@:.bin=.list.orig) -o $$(@:.bin=.list-o) $$<
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib
# check if the result bin is the same as without listing file
# check if the result bin is the same as without listing file
$(ISEQUAL) $$@ $$(@:.bin=.list-bin)
ifneq ($(wildcard $1.list-ref),)
# we have a reference file, compare that, too
# we have a reference file, compare that, too
# remove first line which contains a version number
# remove first line which contains a version number
tail -n +2 $$(@:.bin=.lst.orig) > $$(@:.bin=.lst)
$(ISEQUAL) $1.list-ref $$(@:.bin=.lst)
endif

60
test/val/bug1675-ub.c Normal file
View File

@ -0,0 +1,60 @@
/* #1675 - Some UB cases of bit-shifts */
#include <stdio.h>
int unexpected = 0;
void Test_UB(void)
{
{
/* UB per standard, lhs expected in cc65: (int)-32768 */
if (!((0x4000 << 1) < 0)) {
++unexpected;
printf("Expected: (0x4000 << 1) < 0, got lhs: %ld\n", (long)(0x4000 << 1));
}
}
{
/* UB per standard, lhs expected in cc65: (long)-2147483648L */
if (!((0x40000000 << 1) < 0)) {
++unexpected;
printf("Expected: (0x40000000 << 1) < 0, got lhs: %ld\n", (long)(0x40000000 << 1));
}
}
{
/* UB per standard, lhs expected in cc65: (int)-32768 */
if (!(((unsigned char)0x80 << 8) < 0)) {
++unexpected;
printf("Expected: ((unsigned char)0x80 << 8) < 0, got lhs: %ld\n", (long)((unsigned char)0x80 << 8));
}
}
{
/* UB per standard, lhs expected in cc65: (int)-32768 */
if (!(((short)0x4000L << 1) < 0)) {
++unexpected;
printf("Expected: ((short)0x4000L << 1) < 0, got lhs: %ld\n", (long)((short)0x4000L << 1));
}
}
{
const signed short x = 0x4000;
/* UB per standard, lhs expected in cc65: (int)-32768 */
if (!((x << 1) < 0)) {
++unexpected;
printf("Expected: (x << 1) < 0, got lhs: %ld\n", (long)(x << 1));
}
}
}
int main(void)
{
Test_UB();
if (unexpected != 0) {
printf("Unexpected: %d\n", unexpected);
}
return unexpected;
}

101
test/val/bug1675.c Normal file
View File

@ -0,0 +1,101 @@
/* #1675 - Some corner cases of bit-shifts */
#include <stdio.h>
int failures = 0;
void Test_Defined(void)
{
{
/* Well-defined per standard, lhs expected in cc65: (int)-256 */
if (!(((signed char)0x80 << 1) < 0)) {
++failures;
printf("Expected: ((signed char)0x80 << 1) < 0, got lhs: %ld\n", (long)((signed char)0x80 << 1));
}
}
{
/* Implementation-defined per standard, lhs expected in cc65: (int)-128 */
if (!(((signed char)0x80 >> 1 << 1) < 0)) {
++failures;
printf("Expected: ((signed char)0x80 >> 1 << 1) < 0, got lhs: %ld\n", (long)((signed char)0x80 >> 1 << 1));
}
}
{
int x = 0;
/* Well-defined per standard, lhs expected in cc65: (int)1 */
if (!((1 << (x++, 0)) == 1)) {
++failures;
x = 0;
printf("Expected: (1 << (x++, 0)) == 1, got lhs: %ld\n", (long)(1 << (x++, 0)));
}
/* Well-defined per standard, lhs expected in cc65: (int)1 */
if (!(x == 1)) {
++failures;
printf("Expected: (1 << (x++, 0)) == 1 && x == 1, got x: %d\n", x);
}
}
{
int x = 0, y = 0x100;
/* Well-defined per standard, lhs expected in cc65: (int)128 */
if (!((y >> (x++, 0) >> 1) == 0x80)) {
++failures;
x = 0;
printf("Expected: (y >> (x++, 0) >> 1) == 0x80, got lhs: %ld\n", (long)(y >> (x++, 0) >> 1));
}
/* Well-defined per standard, lhs expected in cc65: (int)1 */
if (!(x == 1)) {
++failures;
printf("Expected: (y >> (x++, 0) >> 1) == 0x80 && x == 1, got x: %d\n", x);
}
}
{
int x = 0, y = 0x100;
/* Well-defined per standard, lhs expected in cc65: (int)1 */
if (!((y >> (x++, 8)) == 1)) {
++failures;
x = 0;
printf("Expected: (y >> (x++, 8)) == 1, got lhs: %ld\n", (long)(y >> (x++, 8)));
}
/* Well-defined per standard, lhs expected in cc65: (int)1 */
if (!(x == 1)) {
++failures;
printf("Expected: (y >> (x++, 8)) == 1 && x == 1, got x: %d\n", x);
}
}
{
const signed char x = 0x80;
/* Well-defined per standard, lhs expected in cc65: (int)-256 */
if (!((x << 1) < 0)) {
++failures;
printf("Expected: (x << 1) < 0, got lhs: %ld\n", (long)(x << 1));
}
}
{
const signed char x = 0x40;
/* Well-defined per standard, lhs expected in cc65: (int)128 */
if (!((x << 1) >= 0)) {
++failures;
printf("Expected: (x << 1) >= 0, got lhs: %ld\n", (long)(x << 1));
}
}
}
int main(void)
{
Test_Defined();
if (failures != 0) {
printf("Failures: %d\n", failures);
}
return failures;
}

30
test/val/bug1690.c Normal file
View File

@ -0,0 +1,30 @@
/* OptCmp1 messed up with labels */
#include <stdio.h>
static int failures = 0;
static unsigned int z = 0xFF23;
int main(void)
{
register unsigned int x = 0x200;
register unsigned int y = 0;
do {
++y;
} while (--x);
if (y != 0x200) {
printf("y should be 0x200, not 0x%X.\n", y);
++failures;;
}
if ((z -= 0x23)) {
/* Passed -- non-zero z looks like non-zero. */
} else {
/* Failed -- only the low byte of z was tested. */
printf("Test thinks non-zero z is zero.\n");
++failures;
}
return failures;
}

44
test/val/bug1696.c Normal file
View File

@ -0,0 +1,44 @@
/*
Copyright 2022 The cc65 Authors
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
Tests of unsigned short/unsigned int vs signed long comparisons;
see https://github.com/cc65/cc65/issues/1696
*/
#include <stdio.h>
static unsigned char failures = 0;
int main(void)
{
unsigned int x = 65535;
unsigned short y = 65535;
if (!(x > 1L)) {
printf("x = %ld but x > 1L failed\n", (long)x);
++failures;
}
if (!(y == 65535L)) {
printf("y = %ld but y == 65535L failed\n", (long)y);
++failures;
}
printf("failures: %u\n", failures);
return failures;
}