[qfcc] Start properly separating target code

I'd gotten tired of all the convoluted progs version checks, and with
the addition of spirv, they're not even always relevant, and adding C
(when I get to it) will make things even worse. However, for now the
first victim is just the parameter/return value size check.
This commit is contained in:
Bill Currie 2024-10-06 14:29:02 +09:00
parent e7401c5ff4
commit 0cf8e7cb41
8 changed files with 228 additions and 24 deletions

View file

@ -0,0 +1,45 @@
/*
target.h
Shared data stuctures for backend targets.
Copyright (C) 2024 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __target_h
#define __target_h
typedef struct type_s type_t;
typedef struct {
bool (*value_too_large) (const type_t *val_type);
} target_t;
extern target_t current_target;
extern target_t v6_target;
extern target_t v6p_target;
extern target_t ruamoko_target;
extern target_t spirv_target;
bool target_set_backend (const char *tgt);
#endif//__target_h

View file

@ -73,12 +73,15 @@ qfcc_SOURCES = \
tools/qfcc/source/qp-parse.y \
tools/qfcc/source/reloc.c \
tools/qfcc/source/shared.c \
tools/qfcc/source/spirv.c \
tools/qfcc/source/statements.c \
tools/qfcc/source/strpool.c \
tools/qfcc/source/struct.c \
tools/qfcc/source/switch.c \
tools/qfcc/source/symtab.c \
tools/qfcc/source/target.c \
tools/qfcc/source/target_rua.c \
tools/qfcc/source/target_spirv.c \
tools/qfcc/source/target_v6.c \
tools/qfcc/source/type.c \
tools/qfcc/source/value.c \
$(tracy_src)

View file

@ -64,6 +64,7 @@
#include "tools/qfcc/include/statements.h"
#include "tools/qfcc/include/strpool.h"
#include "tools/qfcc/include/symtab.h"
#include "tools/qfcc/include/target.h"
#include "tools/qfcc/include/type.h"
#include "tools/qfcc/include/value.h"
@ -939,6 +940,7 @@ find_function (const expr_t *fexpr, const expr_t *params)
int
value_too_large (const type_t *val_type)
{
return current_target.value_too_large (val_type);
if ((options.code.progsversion < PROG_VERSION
&& type_size (val_type) > type_size (&type_param))
|| (options.code.progsversion == PROG_VERSION

View file

@ -52,6 +52,7 @@
#include "tools/qfcc/include/rua-lang.h"
#include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/strpool.h"
#include "tools/qfcc/include/target.h"
#include "tools/qfcc/include/type.h"
options_t options = {
@ -520,22 +521,7 @@ parse_code_option (const char *opt)
bool flag = true;
if (!(strncasecmp (opt, "target=", 7))) {
const char *tgt = opt + 7;
if (!strcasecmp (tgt, "v6")) {
options.code.progsversion = PROG_ID_VERSION;
} else if (!strcasecmp (tgt, "v6p")) {
options.code.progsversion = PROG_V6P_VERSION;
} else if (!strcasecmp (tgt, "ruamoko")) {
options.code.progsversion = PROG_VERSION;
} else if (!strcasecmp (tgt, "spir-v")) {
options.code.progsversion = PROG_VERSION;
options.code.spirv = true;
options.code.no_vararg = true;
} else {
fprintf (stderr, "unknown target: %s\n", tgt);
exit (1);
}
return true;
return target_set_backend (opt + 7);
}
if (!strncasecmp (opt, "no-", 3)) {
flag = false;
@ -692,25 +678,25 @@ DecodeArgs (int argc, char **argv)
case OPT_EXTENDED:
options.traditional = 1;
options.advanced = false;
options.code.progsversion = PROG_ID_VERSION;
target_set_backend ("v6");
options.code.const_initializers = true;
break;
case OPT_TRADITIONAL:
options.traditional = 2;
options.advanced = 0;
options.code.progsversion = PROG_ID_VERSION;
target_set_backend ("v6");
options.code.const_initializers = true;
break;
case OPT_ADVANCED:
options.traditional = 0;
options.advanced = 1;
options.code.progsversion = PROG_V6P_VERSION;
target_set_backend ("v6p");
options.code.const_initializers = false;
break;
case OPT_RUAMOKO:
options.traditional = 0;
options.advanced = 2;
options.code.progsversion = PROG_VERSION;
target_set_backend ("ruamoko");
options.code.const_initializers = false;
break;
case OPT_BLOCK_DOT:
@ -822,7 +808,7 @@ DecodeArgs (int argc, char **argv)
options.traditional = 2;
options.advanced = false;
if (!options.code.progsversion) {
options.code.progsversion = PROG_ID_VERSION;
target_set_backend ("v6");
}
if (!options_user_set.code.ifstring) {
options.code.ifstring = false;
@ -840,8 +826,9 @@ DecodeArgs (int argc, char **argv)
options.math.vector_mult = QC_DOT;
}
}
if (!options.code.progsversion)
options.code.progsversion = PROG_VERSION;
if (!options.code.progsversion) {
target_set_backend ("ruamoko");
}
if (!options.traditional) {
// avanced=2 requires the Ruamoko ISA
options.advanced = 2 - (options.code.progsversion < PROG_VERSION);

View file

@ -0,0 +1,63 @@
/*
target.c
Shared data stuctures for backend targets.
Copyright (C) 2024 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <strings.h>
#include <stdlib.h>
#include "QF/progs/pr_comp.h"
#include "tools/qfcc/include/options.h"
#include "tools/qfcc/include/target.h"
target_t current_target;
bool
target_set_backend (const char *tgt)
{
if (!strcasecmp (tgt, "v6")) {
current_target = v6_target;
options.code.progsversion = PROG_ID_VERSION;
} else if (!strcasecmp (tgt, "v6p")) {
current_target = v6p_target;
options.code.progsversion = PROG_V6P_VERSION;
} else if (!strcasecmp (tgt, "ruamoko")) {
current_target = ruamoko_target;
options.code.progsversion = PROG_VERSION;
} else if (!strcasecmp (tgt, "spir-v")) {
current_target = spirv_target;
options.code.progsversion = PROG_VERSION;
options.code.spirv = true;
options.code.no_vararg = true;
} else {
fprintf (stderr, "unknown target: %s\n", tgt);
exit (1);
}
return true;
}

View file

@ -0,0 +1,45 @@
/*
target_rua.c
Ruamoko progs backend.
Copyright (C) 2024 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/progs/pr_comp.h"
#include "tools/qfcc/include/function.h"
#include "tools/qfcc/include/target.h"
#include "tools/qfcc/include/type.h"
static bool
ruamoko_value_too_large (const type_t *val_type)
{
return type_size (val_type) > MAX_DEF_SIZE;
}
target_t ruamoko_target = {
.value_too_large = ruamoko_value_too_large,
};

View file

@ -44,8 +44,19 @@
#include "tools/qfcc/include/statements.h"
#include "tools/qfcc/include/strpool.h"
#include "tools/qfcc/include/symtab.h"
#include "tools/qfcc/include/target.h"
#include "tools/qfcc/include/type.h"
static bool
spirv_value_too_large (const type_t *val_type)
{
return false;
}
target_t spirv_target = {
.value_too_large = spirv_value_too_large,
};
typedef struct spirvctx_s {
defspace_t *space;
defspace_t *linkage;

View file

@ -0,0 +1,48 @@
/*
target_v6.c
V6 and V6+ progs backends.
Copyright (C) 2024 Bill Currie <bill@taniwha.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/progs/pr_comp.h"
#include "tools/qfcc/include/target.h"
#include "tools/qfcc/include/type.h"
static bool
v6_value_too_large (const type_t *val_type)
{
return type_size (val_type) > type_size (&type_param);
}
target_t v6_target = {
.value_too_large = v6_value_too_large,
};
target_t v6p_target = {
.value_too_large = v6_value_too_large,
};