Skip to content

Commit

Permalink
fixed #14: some bug fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kray-G committed Oct 29, 2019
1 parent db44b75 commit fcebdbc
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 16 deletions.
31 changes: 20 additions & 11 deletions src/backend/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,19 @@ static struct immediate constant(int64_t n, int w)
return imm;
}

/*
* Check if operand can be represented as a 32 bit constant, which is
* the largest width allowed for many instructions.
*/
static int is_int_constant(struct var v)
{
return v.kind == IMMEDIATE
&& (is_integer(v.type) || is_pointer(v.type))
&& !v.symbol
&& (size_of(v.type) < 4
|| (v.imm.i <= INT_MAX && v.imm.i >= INT_MIN));
}

/*
* Return smallest type big enough to cover the i'th eightbyte slice of
* aggregate type. Scalar types are returned as is.
Expand Down Expand Up @@ -710,8 +723,13 @@ static void push(struct var v)
emit(INSTR_PUSH, OPT_MEM, location(address(0, SI, 0, 0), 8));
}
} else if (is_scalar(v.type)) {
if (v.kind == IMMEDIATE && size_of(v.type) < 8 && !is_real(v.type)) {
emit(INSTR_PUSH, OPT_IMM, value_of(v, 8));
if (v.kind == IMMEDIATE && is_int_constant(v)) {
if (size_of(v.type) == 8) {
load_int(v, AX, 8);
emit(INSTR_PUSH, OPT_REG, reg(AX, 8));
} else {
emit(INSTR_PUSH, OPT_IMM, value_of(v, 8));
}
} else {
/*
* Not possible to push SSE registers, so load as if normal
Expand Down Expand Up @@ -2183,15 +2201,6 @@ static int operand_equal(struct var a, struct var b)
&& a.offset == b.offset;
}

static int is_int_constant(struct var v)
{
return v.kind == IMMEDIATE
&& (is_integer(v.type) || is_pointer(v.type))
&& !v.symbol
&& (size_of(v.type) < 8
|| (v.imm.i <= INT_MAX && v.imm.i >= INT_MIN));
}

static enum reg compile_add(
struct var target,
Type type,
Expand Down
4 changes: 2 additions & 2 deletions src/parser/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ static struct expression add(
l.offset += r.imm.i * size;
expr = as_expr(l);
} else if (is_constant(l) && r.kind == IMMEDIATE) {
l.imm.i += r.imm.i;
l.imm.i += r.imm.i * size;
expr = as_expr(l);
} else if (r.kind != IMMEDIATE || r.imm.i) {
type = l.type;
Expand Down Expand Up @@ -678,7 +678,7 @@ static struct expression sub(
l.offset -= r.imm.i * size;
expr = as_expr(l);
} else if (is_constant(l) && r.kind == IMMEDIATE) {
l.imm.i -= r.imm.i;
l.imm.i -= r.imm.i * size;
expr = as_expr(l);
} else if (is_immediate_false(as_expr(r))) {
expr = as_expr(l);
Expand Down
16 changes: 15 additions & 1 deletion src/parser/initializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,13 @@ static struct block *initialize_array(
{
int is_designator;
Type type, elem;
size_t initial, width, i, c;
size_t initial, width, count, i, c;

assert(is_array(target.type));
assert(target.kind == DIRECT);

i = c = 0;
count = is_complete(target.type) ? type_array_len(target.type) : 0;
type = target.type;
elem = type_next(type);
width = size_of(elem);
Expand Down Expand Up @@ -461,10 +462,23 @@ static struct block *initialize_array(
i += 1;
c = i > c ? i : c;
if (has_next_array_element(state, &is_designator)) {
if (!is_designator && count && c >= count)
break;
consume(',');
} else break;
}
}
if (state == CURRENT) {
if (peek().token == ',') {
next();
if (peek().token != '}') {
warning("Length of array initializer elements exceeds target array size.");
}
}
while (peek().token != '}' && peek().token != END) {
next();
}
}

if (!is_complete(type) || !size_of(type)) {
assert(is_array(target.symbol->type));
Expand Down
1 change: 1 addition & 0 deletions src/parser/typetree.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ INTERNAL Type type_create_function(Type next);
INTERNAL Type type_create_array(Type next, size_t count);
INTERNAL Type type_create_incomplete(Type next);
INTERNAL Type type_create_vla(Type next, const struct symbol *count);
INTERNAL Type type_copy_incomplete(Type type);

/* Add const, volatile, and restrict qualifiers to type. */
INTERNAL Type type_set_const(Type type);
Expand Down
9 changes: 9 additions & 0 deletions test/test-lacc/initialize-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ struct {
int k;
} obj = {1, 2, 3,};

struct {
long a[4];
long b;
} s6[] = { 1, 2, 3, -1L, 5, 6, };

void verify(void) {
int i, j;
for (i = 0; i < 2; ++i)
Expand All @@ -31,6 +36,10 @@ void verify(void) {
printf("pc = {{%d, %d, %d, %d}}\n", pc.e[0], pc.e[1], pc.e[2], pc.e[3]);
printf("obj = {{%d, %d, %d, %d}, %d}, size = %lu\n",
obj.v[0], obj.v[1], obj.v[2], obj.v[3], obj.k, sizeof(obj));
for (i = 0; i < 2; ++i) {
printf("s6[%d]: {{%ld, %ld, %ld, %ld}, %ld}\n", i,
s6[i].a[0], s6[i].a[0], s6[i].a[0], s6[i].a[0], s6[i].b);
}
}

int arr[] = {1, 2, 3, 4, 5};
Expand Down
24 changes: 24 additions & 0 deletions test/test-lacc/pointer-immediate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <assert.h>
#include <stdio.h>

typedef float vec_t[3];

typedef struct {
vec_t loc;
} point_t;

static int offsets[] = {
(unsigned long)&((point_t*)0)->loc[0],
(unsigned long)&((point_t*)0)->loc[2],
(unsigned long)&((vec_t*)0)[1]
};

int main(void) {
int *a = (((int*) 0x10) - 2);
int *b = (((int*) 0x10) + 2);

assert(a == (int *) 0x08);
assert(b == (int *) 0x18);

return printf("%d, %d, %d\n", offsets[0], offsets[1], offsets[2]);
}
9 changes: 9 additions & 0 deletions test/test-lacc/push-immediate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
int printf(const char *, ...);

int foo(int a, int b, int c, int d, int e, int f, unsigned int g) {
return printf("%d, %d, %d, %d, %d, %d, %u\n", a, b, c, d, e, f, g);
}

int main(void) {
return foo(1, 2, 3, 4, 5, 6, 0xFF000000u);
}
6 changes: 4 additions & 2 deletions test/test-lacc/test.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ if NOT "%1" == "" SET GEN=..\..\kcc.exe -x

:CLEANUP
pushd %~dp0
del *.expect > NUL 2>&1
del *.result > NUL 2>&1
del /S /Q *.expect > NUL 2>&1
del /S /Q *.result > NUL 2>&1

:DO_TEST
REM c11
Expand Down Expand Up @@ -202,6 +202,7 @@ call :TEST params-mixed.c
call :TEST params-system-v.c
call :TEST partial-initialization.c
call :TEST pointer-diff.c
call :TEST pointer-immediate.c
call :TEST pointer.c
call :TEST preprocess-expression.c
call :TEST preprocess.c
Expand All @@ -210,6 +211,7 @@ REM call :TEST printstr.c
call :TEST promote-unsigned.c
call :TEST prototype-scope-enum.c
call :TEST ptrdiff.c
call :TEST push-immediate.c
call :TEST qualifier-repeat.c
call :TEST register-param.c
REM call :TEST return-bitfield.c
Expand Down

0 comments on commit fcebdbc

Please sign in to comment.