[qfcc] Un-dereference src expression early for movep

The VM has no pointer to direct reference move instruction.

Fixes #9
This commit is contained in:
Bill Currie 2021-06-30 20:05:27 +09:00
parent 9d140d1d15
commit ddc6f6bcb0
3 changed files with 44 additions and 7 deletions

View file

@ -787,9 +787,13 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
}
type = st_memset;
if (is_indirect (dst_expr)) {
goto dereference_dst;
need_ptr = 1;
}
} else {
if (is_indirect (src_expr)) {
src_expr = expr_file_line (address_expr (src_expr, 0, 0), e);
need_ptr = 1;
}
if (!src) {
// This is the very right-hand node of a non-nil assignment chain
// (there may be more chains somwhere within src_expr, but they
@ -802,15 +806,15 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
if (op) {
*op = src;
}
if (is_indirect (dst_expr) || is_indirect (src_expr)) {
if (is_indirect (dst_expr)) {
src = operand_address (src, src_expr);
goto dereference_dst;
need_ptr = 1;
}
}
if (0) {
dereference_dst:
// dst_expr is a dereferenced pointer, so need to un-dereference it
// to get the pointer and switch to storep instructions.
if (need_ptr) {
// dst_expr and/or src_expr are dereferenced pointers, so need to
// un-dereference dst_expr to get the pointer and switch to movep
// or memsetp instructions.
dst_expr = expr_file_line (address_expr (dst_expr, 0, 0), e);
need_ptr = 1;
}

View file

@ -34,6 +34,7 @@ test_progs_dat=\
tools/qfcc/test/paramret.dat \
tools/qfcc/test/postop.dat \
tools/qfcc/test/ptraliasenc.dat \
tools/qfcc/test/ptrstructcast.dat \
tools/qfcc/test/quaternion.dat \
tools/qfcc/test/return-ivar.dat \
tools/qfcc/test/sendv.dat \
@ -394,6 +395,16 @@ tools/qfcc/test/ptraliasenc.run: $(qfcc_test_run_deps)
include $(ptraliasenc_dep) # am--include-marker
r_depfiles_remade += $(ptraliasenc_dep)
tools_qfcc_test_ptrstructcast_dat_SOURCES=tools/qfcc/test/ptrstructcast.r
ptrstructcast_obj=$(tools_qfcc_test_ptrstructcast_dat_SOURCES:.r=.o)
ptrstructcast_dep=$(call qcautodep,$(tools_qfcc_test_ptrstructcast_dat_SOURCES))
tools/qfcc/test/ptrstructcast.dat$(EXEEXT): $(ptrstructcast_obj) $(QFCC_DEP)
$(V_QFCCLD)$(QLINK) -o $@ $(ptrstructcast_obj)
tools/qfcc/test/ptrstructcast.run: $(qfcc_test_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-run $@
include $(ptrstructcast_dep) # am--include-marker
r_depfiles_remade += $(ptrstructcast_dep)
tools_qfcc_test_quaternion_dat_SOURCES=tools/qfcc/test/quaternion.r
quaternion_obj=$(tools_qfcc_test_quaternion_dat_SOURCES:.r=.o)
quaternion_dep=$(call qcautodep,$(tools_qfcc_test_quaternion_dat_SOURCES))

View file

@ -0,0 +1,22 @@
typedef struct Point_s {
int x;
int y;
} Point;
typedef struct Extent_s {
int width;
int height;
} Extent;
int
foo (Point p)
{
Extent e = *(Extent *)&p;
return e.width * e.height;
}
int
main (void)
{
return foo ({ 6, 7 }) != 42;
}