Skip to content

Commit

Permalink
Merge pull request #208 from kernigh/kernigh-data8
Browse files Browse the repository at this point in the history
8-byte long long in ACK C for i386, m68020
  • Loading branch information
davidgiven authored Oct 7, 2019
2 parents c2604db + b9bd899 commit 1bf045f
Show file tree
Hide file tree
Showing 99 changed files with 2,652 additions and 384 deletions.
7 changes: 2 additions & 5 deletions lang/cem/cemcom.ansi/BigPars
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#define SZ_WORD 4
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_LNGLNG -1
#define SZ_FLOAT 4
#define SZ_DOUBLE 8
#define SZ_LNGDBL 8 /* for now */
Expand All @@ -66,6 +67,7 @@
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#define AL_LNGLNG SZ_WORD
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#define AL_LNGDBL SZ_WORD
Expand Down Expand Up @@ -115,11 +117,6 @@
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */


!File: spec_arith.h
/* describes internal compiler arithmetics */
#undef SPECIAL_ARITHMETICS /* something different from native long */


!File: static.h
#define GSTATIC /* for large global "static" arrays */

Expand Down
110 changes: 76 additions & 34 deletions lang/cem/cemcom.ansi/LLlex.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Lpars.h"
#include "class.h"
#include "sizes.h"
#include "type.h" /* no_long_long() */
#include "error.h"
#include "domacro.h"
#include "specials.h" /* registration of special identifiers */
Expand All @@ -37,7 +38,6 @@ int LexSave = 0; /* last character read by GetChar */

#define FLG_ESEEN 0x01 /* possibly a floating point number */
#define FLG_DOTSEEN 0x02 /* certainly a floating point number */
extern arith full_mask[];

#ifdef LINT
extern int lint_skip_comment;
Expand Down Expand Up @@ -594,10 +594,12 @@ static void strflt2tok(char fltbuf[], struct token* ptok)
static void strint2tok(char intbuf[], struct token* ptok)
{
register char* cp = intbuf;
int base = 10;
arith val = 0, dig, ubound;
int uns_flg = 0, lng_flg = 0, malformed = 0, ovfl = 0;
int fund;
int base = 10, dig;
unsigned writh val = 0, ubound;
int uns_flg = 0, lng_flg = 0, lnglng_flg = 0;
int malformed = 0, ovfl = 0;
unsigned writh uint_mask, ulng_mask, ulnglng_mask;
int cut, fund;

assert(*cp != '-');
if (*cp == '0')
Expand All @@ -611,11 +613,8 @@ static void strint2tok(char intbuf[], struct token* ptok)
else
base = 8;
}
/* The upperbound will be the same as when computed with
* max_unsigned_arith / base (since base is even). The problem here
* is that unsigned arith is not accepted by all compilers.
*/
ubound = max_arith / (base / 2);
/* The upperbound checks if val * base would overflow. */
ubound = ~(unsigned writh)0 / base;

while (is_hex(*cp))
{
Expand All @@ -626,10 +625,10 @@ static void strint2tok(char intbuf[], struct token* ptok)
}
else
{
if (val < 0 || val > ubound)
if (val > ubound)
ovfl++;
val *= base;
if (val < 0 && val + dig >= 0)
if (val > val + dig)
ovfl++;
val += dig;
}
Expand All @@ -639,7 +638,16 @@ static void strint2tok(char intbuf[], struct token* ptok)
while (*cp)
{
if (*cp == 'l' || *cp == 'L')
lng_flg++;
{
if (*cp == *(cp + 1))
{
/* 'll' or 'LL' */
lnglng_flg++;
cp++;
}
else
lng_flg++;
}
else if (*cp == 'u' || *cp == 'U')
uns_flg++;
else
Expand All @@ -658,59 +666,93 @@ static void strint2tok(char intbuf[], struct token* ptok)
}
else
{
if (lng_flg > 1)
if (lng_flg + lnglng_flg > 1)
lexerror("only one long suffix allowed");
if (uns_flg > 1)
lexerror("only one unsigned suffix allowed");
}

/* Get masks like 0XFFFF, 0XFFFFFFFF as unsigned values. */
uint_mask = (unsigned writh)full_mask[(int)int_size];
ulng_mask = (unsigned writh)full_mask[(int)long_size];
if (lnglng_size < 0)
ulnglng_mask = 0;
else
ulnglng_mask = (unsigned writh)full_mask[(int)lnglng_size];

/* If a decimal literal with no suffix is too big for int
and long, then C89 tries unsigned long, but C99 tries
long long (WG14, Rationale for C99, C99RationaleV5.10.pdf,
6.4.4.1 Integer constants).
This compiler follows C89 when the literal has no
long long suffix.
*/
cut = 0;
if (ovfl)
{
lexwarning("overflow in constant");
fund = ULONG;
cut = 1; /* cut the size of the constant */
}
else if (!lng_flg && (val & full_mask[(int)int_size]) == val)
else if (!lng_flg && !lnglng_flg && (val & uint_mask) == val)
{
if (val >= 0 && val <= max_int)
{
if ((val & (uint_mask >> 1)) == val)
fund = INT;
}
else if (int_size == long_size)
else if (base == 10 && !uns_flg)
{
fund = UNSIGNED;
if ((val & (ulng_mask >> 1)) == val)
fund = LONG;
else
fund = ULONG;
}
else if (base == 10 && !uns_flg)
fund = LONG;
else
fund = UNSIGNED;
}
else if ((val & full_mask[(int)long_size]) == val)
else if (!lnglng_flg && (val & ulng_mask) == val)
{
if (val >= 0)
if ((val & (ulng_mask >> 1)) == val)
fund = LONG;
else
fund = ULONG;
}
else if (lnglng_flg && (val & ulnglng_mask) == val)
{
if ((val & (ulnglng_mask >> 1)) == val)
fund = LNGLNG;
else
fund = ULNGLNG;
}
else if (lnglng_flg && no_long_long())
fund = ERRONEOUS;
else
{ /* sizeof(arith) is greater than long_size */
assert(arith_size > long_size);
{
assert(sizeof(val) > long_size ||
(lnglng_size >= 0 && sizeof(val) > lnglng_size));
lexwarning("constant too large for target machine");
/* cut the size to prevent further complaints */
val &= full_mask[(int)long_size];
fund = ULONG;
cut = 1;
}
if (lng_flg)
if (cut)
{
/* fund can't be INT */
if (fund == UNSIGNED)
/* cut the size to prevent further complaints */
if (lnglng_flg)
{
fund = ULNGLNG;
val &= ulnglng_mask;
}
else
{
fund = ULONG;
val &= ulng_mask;
}
}
if (uns_flg)
{
if (fund == INT)
fund = UNSIGNED;
else if (fund == LONG)
fund = ULONG;
else if (fund == LNGLNG)
fund = ULNGLNG;
}
ptok->tk_fund = fund;
ptok->tk_ival = val;
ptok->tk_ival = (writh)val;
}
2 changes: 1 addition & 1 deletion lang/cem/cemcom.ansi/LLlex.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct token {
char *tok_bts; /* row of bytes */
int tok_len; /* length of row of bytes */
} tok_string;
arith tok_ival; /* for INTEGER */
writh tok_ival; /* for INTEGER */
char *tok_fval; /* for FLOATING */
} tok_data;
};
Expand Down
7 changes: 2 additions & 5 deletions lang/cem/cemcom.ansi/SmallPars
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#define SZ_WORD 4
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_LNGLNG -1
#define SZ_FLOAT 4
#define SZ_DOUBLE 8
#define SZ_LNGDBL 8 /* for now */
Expand All @@ -66,6 +67,7 @@
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#define AL_LNGLNG SZ_WORD
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#define AL_LNGDBL SZ_WORD
Expand Down Expand Up @@ -115,11 +117,6 @@
/*#define NOBITFIELD 1 /* if NOT defined, implement bitfields */


!File: spec_arith.h
/* describes internal compiler arithmetics */
#undef SPECIAL_ARITHMETICS /* something different from native long */


!File: static.h
#define GSTATIC /* for large global "static" arrays */

Expand Down
2 changes: 2 additions & 0 deletions lang/cem/cemcom.ansi/align.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef NOCROSS
extern int
short_align, word_align, int_align, long_align,
lnglng_align,
float_align, double_align, lngdbl_align,
pointer_align,
struct_align, union_align;
Expand All @@ -18,6 +19,7 @@ extern int
#define word_align ((int)AL_WORD)
#define int_align ((int)AL_INT)
#define long_align ((int)AL_LONG)
#define lnglng_align ((int)AL_LNGLNG)
#define float_align ((int)AL_FLOAT)
#define double_align ((int)AL_DOUBLE)
#define lngdbl_align ((int)AL_LNGDBL)
Expand Down
Loading

0 comments on commit 1bf045f

Please sign in to comment.