mirror of
https://github.com/cc65/cc65.git
synced 2024-07-12 21:30:02 +00:00
82 lines
2.5 KiB
C
82 lines
2.5 KiB
C
/** This test is related to GitHub issue 895
|
|
** https://github.com/cc65/cc65/issues/895
|
|
**
|
|
** The OptCmp8 optimization attempts to eliminate an unnecessary
|
|
** comparison and branch when the operands of the comparison are
|
|
** known to be constant at compile time.
|
|
**
|
|
** For 8-bit types it worked well, but for larger types it failed
|
|
** to generate correct code. The bug manifest as a branch on an
|
|
** uninitialized carry flag.
|
|
**
|
|
** This does four tests for each type tested:
|
|
** 1: < with carry clear
|
|
** 2: >= with carry clear
|
|
** 3: < with carry set
|
|
** 4: >= with carry set
|
|
*/
|
|
|
|
#include "unittest.h"
|
|
|
|
signed char sca, scb;
|
|
signed int sia, sib;
|
|
signed long sla, slb;
|
|
|
|
unsigned char uca, ucb;
|
|
unsigned int uia, uib;
|
|
unsigned long ula, ulb;
|
|
|
|
#define OPTCMP8TEST(vara,varb,startb,starta,cmpa,setb,printterm,typename,name) \
|
|
void name ## 1(void) { \
|
|
varb = startb; \
|
|
asm("clc"); \
|
|
vara = starta; \
|
|
if (vara < cmpa) varb = setb; \
|
|
ASSERT_AreEqual(startb, varb, printterm, "Incorrect optimization of " typename " comparison (1: < clc)."); \
|
|
} \
|
|
void name ## 2(void) { \
|
|
varb = startb; \
|
|
asm("sec"); \
|
|
vara = starta; \
|
|
if (vara < cmpa) varb = setb; \
|
|
ASSERT_AreEqual(startb, varb, printterm, "Incorrect optimization of " typename " comparison (2: < sec)."); \
|
|
} \
|
|
void name ## 3(void) { \
|
|
varb = startb; \
|
|
asm("clc"); \
|
|
vara = starta; \
|
|
if (vara >= cmpa) varb = setb; \
|
|
ASSERT_AreEqual(setb, varb, printterm, "Incorrect optimization of " typename " comparison (3: >= clc)."); \
|
|
} \
|
|
void name ## 4(void) { \
|
|
varb = startb; \
|
|
asm("sec"); \
|
|
vara = starta; \
|
|
if (vara >= cmpa) varb = setb; \
|
|
ASSERT_AreEqual(setb, varb, printterm, "Incorrect optimization of " typename " comparison (4: >= sec)."); \
|
|
}
|
|
|
|
#define RUNOPTCMP8TEST(name) \
|
|
name ## 1(); \
|
|
name ## 2(); \
|
|
name ## 3(); \
|
|
name ## 4();
|
|
|
|
OPTCMP8TEST(sca,scb,-20,100,50,5,"%d","signed char",signed_char);
|
|
OPTCMP8TEST(uca,ucb,20,100,50,5,"%u","unsigned char",unsigned_char);
|
|
OPTCMP8TEST(sia,sib,-2000,1000,500,50,"%d","signed int",signed_int);
|
|
OPTCMP8TEST(uia,uib,2000,1000,500,50,"%u","unsigned int",unsigned_int);
|
|
OPTCMP8TEST(sla,slb,-200000L,100000L,50000L,5000L,"%d","signed long",signed_long);
|
|
OPTCMP8TEST(ula,ulb,200000UL,100000UL,50000UL,5000UL,"%u","unsigned long",unsigned_long);
|
|
|
|
TEST
|
|
{
|
|
RUNOPTCMP8TEST(signed_char);
|
|
RUNOPTCMP8TEST(unsigned_char);
|
|
RUNOPTCMP8TEST(signed_int);
|
|
RUNOPTCMP8TEST(unsigned_int);
|
|
RUNOPTCMP8TEST(signed_long);
|
|
RUNOPTCMP8TEST(unsigned_long);
|
|
}
|
|
ENDTEST
|