cc65: Compiler produces invalid code
I came back to a project of mine and noticed cc65 produces code that does not assemble (branch too far). Bisecting shows this happened after commit d8a3938f2b8d6c53c2f75b5a07964e8beef746a5
@colinleroy would you have a look please? It looks like the optimizer replaces some JNEs by BNEs when it shouldn’t do that
Attached is a somewhat stripped down test case
cl65 --add-source -Osir --codesize 180 -Wc --local-strings -t none -o bug.prg bug.c
#include <string.h>
typedef unsigned char FRESULT;
typedef unsigned char	BYTE;
typedef unsigned long	DWORD;
typedef unsigned short	WORD;
typedef BYTE	DRESULT;
typedef struct _FATFS_ {
	BYTE	fs_type;	/*!< FAT sub type */
	BYTE	csize;		/*!< Number of sectors per cluster */
	BYTE	n_fats;		/*!< Number of FAT copies */
	BYTE	wflag;		/*!< win[] dirty flag (1:must be written back) */
	BYTE	fsi_flag;	/*!< fsinfo dirty flag (1:must be written back) */
	WORD	n_rootdir;	/*!< Number of root directory entries (0 on FAT32) */
	DWORD	last_clust;	/*!< Last allocated cluster */
	DWORD	free_clust;	/*!< Number of free clusters */
	DWORD	fsi_sector;	/*!< fsinfo sector */
	DWORD	cdir;		/*!< Current directory (0:root)*/
	DWORD	sects_fat;	/*!< Sectors per fat */
	DWORD	max_clust;	/*!< Maximum cluster# + 1. Number of clusters is max_clust - 2 */
	DWORD	fatbase;	/*!< FAT start sector */
	DWORD	dirbase;	/*!< Root directory start sector (Cluster# on FAT32) */
	DWORD	database;	/*!< Data start sector */
	DWORD	winsect;	/*!< Current sector appearing in the win[] */
} FATFS;
FATFS FatFsObj; /* actually extern, but both produces the error */
#pragma zpsym ("FatFsObj")          /* this is the problem */
#define FR_OK 0
#define FS_FAT32	3
#define BS_55AA			510
#define	FSI_LeadSig		0
#define	FSI_StrucSig		484
#define	FSI_Free_Count		488
#define	FSI_Nxt_Free		492
BYTE FatFsObjwin[512];
#define	ST_WORD(ptr,val)	*(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define	ST_DWORD(ptr,val)	*(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
DRESULT __fastcall__ disk_write_win (DWORD sector)
{
    return 0;
}
FRESULT __fastcall__ move_window (DWORD sector)
{
    return 0;
}
FRESULT __fastcall__ sync (void)
{
	FRESULT res;
	res = move_window(0);
	if (res == FR_OK) {
		if ((FatFsObj.fs_type == FS_FAT32) && FatFsObj.fsi_flag) {
			FatFsObj.winsect = 0;
			memset(FatFsObjwin, 0, 512);
			ST_WORD(FatFsObjwin+BS_55AA, 0xAA55);
			ST_DWORD(FatFsObjwin+FSI_LeadSig, 0x41615252);
			ST_DWORD(FatFsObjwin+FSI_StrucSig, 0x61417272);
			ST_DWORD(FatFsObjwin+FSI_Free_Count, FatFsObj.free_clust);
			ST_DWORD(FatFsObjwin+FSI_Nxt_Free, FatFsObj.last_clust);
			disk_write_win(FatFsObj.fsi_sector);
			FatFsObj.fsi_flag = 0;
		}
	}
	return res;
}
int main (void)
{
    sync();
    return 0;
}
About this issue
- Original URL
 - State: closed
 - Created 6 months ago
 - Comments: 22 (22 by maintainers)
 
Commits related to this issue
- Fix #2357 - Copy est.size and flags of op when moving it — committed to colinleroy/cc65 by colinleroy 6 months ago
 - Merge pull request #2359 from colinleroy/fix-2357 Fix #2357 - Copy est.size and flags of op when moving it — committed to cc65/cc65 by mrdudz 6 months ago
 - Revert "Fix #2357 - Copy est.size and flags of op when moving it" — committed to cc65/cc65 by mrdudz 6 months ago
 - Merge pull request #2360 from cc65/revert-2359-fix-2357 Revert "Fix #2357 - Copy est.size and flags of op when moving it" — committed to cc65/cc65 by mrdudz 6 months ago
 - Fix #2357 - Copy est.size and flags of op when moving it — committed to colinleroy/cc65 by colinleroy 6 months ago
 - Add test case for bug #2357 — committed to colinleroy/cc65 by colinleroy 5 months ago
 - Add test case for bug #2357 — committed to colinleroy/cc65 by colinleroy 5 months ago
 - Add test case for bug #2357 — committed to colinleroy/cc65 by colinleroy 5 months ago
 - Merge pull request #2362 from colinleroy/fix-2357-bis Add test case for bug #2357 — committed to cc65/cc65 by mrdudz 5 months ago
 
That was my fault, i screwed it up and had a compiled .s from a previous quick test in the wrong directory (and my makefile picked it up and didnt even recompile). It DOES work with your patch (pfew).
The problem is still creating a test that breaks without and works with your patch 😃
Mmmmh and apparently it still breaks with your patch too. Args
without, of course
note the -c above - so it compiles and assembles (which produces the error) but does not link (that happens much later)
No 😃 This is the FAT library used in the menu system of the Turbo-Chameleon from ICOMP.