Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions lang/cem/cemcom.ansi/ch3mon.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,10 @@ void ch3mon(int oper, struct expr** expp)
{
writh o1 = (*expp)->VL_VALUE;

(*expp)->VL_VALUE = (oper == '-')
? -o1
: ((*expp)->ex_type->tp_unsigned
? (~o1) & full_mask[(int)(*expp)->ex_type->tp_size]
: ~o1);
o1 = (oper == '-') ? -o1 : ~o1;
if ((*expp)->ex_type->tp_unsigned)
o1 &= full_mask[(int)(*expp)->ex_type->tp_size];
(*expp)->VL_VALUE = o1;
}
else if (is_fp_cst(*expp))
switch_sign_fp(*expp);
Expand Down
63 changes: 38 additions & 25 deletions mach/m68020/ncg/table
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,8 @@ from memory2

from memory1
uses DD_REG = {zero_const, 0}
gen move_b %1, %a yields %a
gen move_b %1, %a
killcc. yields %a

from memory2
uses DD_REG
Expand Down Expand Up @@ -6400,18 +6401,20 @@ pat lil loc sru sil $1==$4 && $2==1 && $3==4 call rlil1shsil("lsr #1,")

proc txxand
with test_set_int DD_REG
gen test %1
gen and_i {const,1}, %2
test %1
bxx[1] {slabel, 1f}
bclr {const,0}, %2
clr_i %2
1: yields %2
#if WORD_SIZE==2
with test_set1 DD_REG
#else
with test_set1 + test_set2 DD_REG
#endif
gen test %1
gen and_i {const,1}, %2
test %1
bxx[2] {slabel, 1f}
bclr {const,0}, %2
clr_i %2
1: yields %2

proc txxior
Expand All @@ -6432,19 +6435,21 @@ with test_set1 + test_set2 DD_REG

proc txxand_ouch
with test_set_int DD_REG
gen killcc.
gen and_i {const,1}, %2
killcc.
test %1
bxx[1] {slabel, 1f}
bclr {const,0}, %2
clr_i %2
1: yields %2
#if WORD_SIZE==2
with test_set1 DD_REG
#else
with test_set1 + test_set2 DD_REG
#endif
gen test %1
gen and_i {const,1}, %2
test %1
bxx[2] {slabel, 1f}
bclr {const,0}, %2
clr_i %2
1: yields %2

proc txxior_ouch
Expand Down Expand Up @@ -6480,46 +6485,54 @@ pat tgt ior $2==WORD_SIZE call txxior_ouch("ble", "bls")

proc cmxtxxand
with exact extend1 extend1 DD_REG
gen cmp_b %2, %1
gen and_i {const,1}, %3
cmp_b %2, %1
bxx[2] {llabel,1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with exact extend2 extend2 DD_REG
gen cmp_w %2, %1
gen and_i {const,1}, %3
cmp_w %2, %1
bxx[2] {llabel,1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with exact sconsts any_int DD_REG
uses DD_REG=%1
gen cmp_i %2, %a
gen and_i {const,1}, %3
cmp_i %2, %a
bxx[2] {slabel, 1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with exact any_int sconsts DD_REG
uses DD_REG=%2
gen cmp_i %1, %a
gen and_i {const,1}, %3
cmp_i %1, %a
bxx[1] {slabel, 1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with any_int-sconsts genreg DD_REG
gen cmp_i %1, %2
gen and_i {const,1}, %3
cmp_i %1, %2
bxx[1] {slabel, 1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with genreg any_int-sconsts DD_REG
gen cmp_i %2, %1
gen and_i {const,1}, %3
cmp_i %2, %1
bxx[2] {slabel, 1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with exact immediate_int-sconsts imm_cmp_int DD_REG
gen cmp_i %1, %2
gen and_i {const,1}, %3
cmp_i %1, %2
bxx[1] {slabel, 1f}
bclr {const,0}, %3
clr_i %3
1: yields %3
with exact imm_cmp_int immediate_int-sconsts DD_REG
gen cmp_i %2, %1
gen and_i {const,1}, %3
cmp_i %2, %1
bxx[2] {slabel, 1f}
bclr {const,0}, %3
clr_i %3
1: yields %3

proc cmxtxxior
Expand Down
6 changes: 6 additions & 0 deletions tests/plat/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
"core": [
"tests/plat/core/aar,e,.e",
"tests/plat/core/and,e,.e",
"tests/plat/core/andbool,e,.c",
"tests/plat/core/andv,e,.e",
"tests/plat/core/brk,c,.c",
"tests/plat/core/bss,e,.c",
"tests/plat/core/bytediv,e,.c",
"tests/plat/core/calloc,c,.c",
"tests/plat/core/cii,e,.e",
"tests/plat/core/cmi,e,.e",
Expand All @@ -29,6 +31,8 @@
"tests/plat/core/_dummy,e,.c",
"tests/plat/core/dup,e,.e",
"tests/plat/core/exg,e,.e",
"tests/plat/core/foldcii,e,-O3,.c",
"tests/plat/core/foldoverflow,e,-O3,.c",
"tests/plat/core/inn,e,.e",
"tests/plat/core/intadd,e,.c",
"tests/plat/core/intcmp,e,.c",
Expand All @@ -39,6 +43,8 @@
"tests/plat/core/ior,e,.e",
"tests/plat/core/iorv,e,.e",
"tests/plat/core/lar,e,.e",
"tests/plat/core/mulminus1,e,.c",
"tests/plat/core/negunsigned,e,.c",
"tests/plat/core/newdispose,p,.p",
"tests/plat/core/pascalsets,p,.p",
"tests/plat/core/rck,e,.e",
Expand Down
65 changes: 65 additions & 0 deletions tests/plat/core/andbool,e,.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "test.h"

/* x & (a op b) is x & 0 or x & 1, not "x with bit 0 cleared if false". */

int16_t one = 1;
int16_t two = 2;
int8_t g = 0x40;
int32_t sh = 0;
int ione = 1, itwo = 2, ish = 0;
long lone = 1, ltwo = 2, lsh = 0;

static int16_t f(void)
{
return (int16_t)((int32_t)-8017 >> ((uint8_t)sh & 31))
& (int16_t)((int32_t)-1L && (int16_t)g);
}

static int16_t h(int16_t x)
{
return (int16_t)((int32_t)x >> ((uint8_t)sh & 31)) & (int16_t)(one < two);
}

static int16_t k(int16_t x)
{
return (int16_t)((int32_t)x >> ((uint8_t)sh & 31)) & (int16_t)(one == two);
}

/* The same with int and long operands, for every word size. */

static int ih(int x)
{
return (x >> ish) & (ione < itwo);
}

static int ik(int x)
{
return (x >> ish) & (ione == itwo);
}

static int ic(int x, int a, int b)
{
return (x >> ish) & (a < b);
}

static long lh(long x)
{
return (x >> lsh) & (lone < ltwo);
}

/* Bypasses the CRT, so there's no stdio. */
void _m_a_i_n(void)
{
ASSERT(f() == 1);
ASSERT(h(-8017) == 1);
ASSERT(h(-8018) == 0);
ASSERT(k(-8017) == 0);
ASSERT(ih(-8017) == 1);
ASSERT(ih(-8018) == 0);
ASSERT(ik(-8017) == 0);
ASSERT(ic(-8017, 1, 2) == 1);
ASSERT(ic(-8017, 2, 1) == 0);
ASSERT(lh(-8017L) == 1);

finished();
}
23 changes: 23 additions & 0 deletions tests/plat/core/bytediv,e,.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "test.h"

/* A byte moved into a cleared register sets the condition codes for the
* byte, not the register: dividing by a power of two must not take the
* byte's sign as the register's. */

int16_t l = -300;
int8_t s = -100;

/* Bypasses the CRT, so there's no stdio. */
void _m_a_i_n(void)
{
uint8_t u = (uint8_t)l;

ASSERT((uint8_t)l == 212);
ASSERT((uint8_t)l / 16 == 13);
ASSERT(u / 16 == 13);
ASSERT(u / 4 == 53);
ASSERT((uint8_t)s / 2 == 78);
ASSERT(s / 2 == -50);

finished();
}
79 changes: 79 additions & 0 deletions tests/plat/core/foldcii,e,-O3,.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include "test.h"

/* Narrowing conversions of constants that ego propagates: (int8_t)16384
* is 0. */

int16_t a = 1, b = 2;
int16_t sh = 0;
int16_t fe = 29988;
int32_t fb = -1021131558L;
int8_t arr[8];

static void f(void)
{
uint16_t l = 16384;

arr[((uint8_t)((int32_t)((uint8_t)((uint16_t)((uint8_t)l) << (sh & 7)))
| (int32_t)(((int8_t)l) ? ((uint8_t)fe) : ((uint8_t)fb)))) & 7] = 1;
}

static int16_t g(void)
{
uint16_t l = 16384;

return (int8_t)l ? a : b;
}

static int32_t h(void)
{
uint16_t l = 45219;

return (int32_t)(int16_t)l;
}

/* The same with int, for every word size. */

static int fi(void)
{
int l = 16384;

return (int8_t)l ? a : b;
}

static int ki(void)
{
int l = 384;

return (int8_t)l + 0;
}

static long hi(void)
{
int l = 384;

return (long)(int8_t)l;
}

static void si(void)
{
int l = 16384;

arr[(int8_t)l ? 4 : 2] = 2;
}

/* Bypasses the CRT, so there's no stdio. */
void _m_a_i_n(void)
{
f();
ASSERT(arr[2] == 1);
ASSERT(arr[4] == 0);
ASSERT(g() == 2);
ASSERT(h() == 45219L - 65536L);
ASSERT(fi() == 2);
ASSERT(ki() == -128);
ASSERT(hi() == -128L);
si();
ASSERT(arr[2] == 2);

finished();
}
36 changes: 36 additions & 0 deletions tests/plat/core/foldoverflow,e,-O3,.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "test.h"

/* Unsigned arithmetic on constants that ego propagates into one
* instruction wraps around in the word instead of growing. */

uint16_t r16 = 0;

/* Bypasses the CRT, so there's no stdio. */
void _m_a_i_n(void)
{
unsigned int m = (unsigned int)-1;
unsigned int three = 3;
unsigned int two = 2;
uint16_t a = 12933;
uint16_t b = 20802;
uint32_t big = 0x10000UL;
unsigned int ua = 12933;
unsigned int ub = 20802;

ASSERT(m * three == (unsigned int)-3);
ASSERT(m + two == 1);
ASSERT(three - m == 4);
ASSERT((m << three) == (unsigned int)-8);
ASSERT((uint16_t)(a * b) == 6986);
r16 = 100 / (uint16_t)(a * b);
ASSERT(r16 == 0);
ASSERT(big * big == 0);
ASSERT((big << 16) == 0);
/* Shifting the result of a fold must not see bits beyond the word. */
ASSERT((uint16_t)((uint16_t)(ua * ub) >> 8) == 27);
ASSERT((uint32_t)(big * big) >> 16 == 0);
ASSERT((uint32_t)(big << 16) >> 8 == 0);
ASSERT((m * three) >> 1 == (unsigned int)-3 >> 1);

finished();
}
Loading