aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-cris/cpu.c14
-rw-r--r--target-cris/crisv10-decode.h1
-rw-r--r--target-cris/translate.c36
-rw-r--r--target-cris/translate_v10.c23
-rw-r--r--tests/tcg/cris/Makefile21
-rw-r--r--tests/tcg/cris/check_abs.c4
-rw-r--r--tests/tcg/cris/check_addc.c2
-rw-r--r--tests/tcg/cris/check_addcm.c4
-rw-r--r--tests/tcg/cris/check_addcv17.s65
-rw-r--r--tests/tcg/cris/check_bound.c6
-rw-r--r--tests/tcg/cris/check_ftag.c8
-rw-r--r--tests/tcg/cris/check_int64.c4
-rw-r--r--tests/tcg/cris/check_lz.c2
-rw-r--r--tests/tcg/cris/check_openpf4.c5
-rw-r--r--tests/tcg/cris/check_swap.c2
-rw-r--r--tests/tcg/cris/check_time1.c46
-rw-r--r--tests/tcg/cris/crisutils.h20
-rw-r--r--tests/tcg/cris/sys.c26
-rw-r--r--tests/tcg/cris/sys.h2
19 files changed, 188 insertions, 103 deletions
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index c5a656bb62..d680cfb52b 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -246,6 +246,16 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
}
+static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
+{
+ CPUClass *cc = CPU_CLASS(oc);
+ CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
+
+ ccc->vr = 17;
+ cc->do_interrupt = crisv10_cpu_do_interrupt;
+ cc->gdb_read_register = crisv10_cpu_gdb_read_register;
+}
+
static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
{
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
@@ -273,6 +283,10 @@ static const TypeInfo cris_cpu_model_type_infos[] = {
.parent = TYPE_CRIS_CPU,
.class_init = crisv11_cpu_class_init,
}, {
+ .name = TYPE("crisv17"),
+ .parent = TYPE_CRIS_CPU,
+ .class_init = crisv17_cpu_class_init,
+ }, {
.name = TYPE("crisv32"),
.parent = TYPE_CRIS_CPU,
.class_init = crisv32_cpu_class_init,
diff --git a/target-cris/crisv10-decode.h b/target-cris/crisv10-decode.h
index 587fbdd278..bdb4b6d318 100644
--- a/target-cris/crisv10-decode.h
+++ b/target-cris/crisv10-decode.h
@@ -92,6 +92,7 @@
#define CRISV10_IND_JUMP_M 4
#define CRISV10_IND_DIP 5
#define CRISV10_IND_JUMP_R 6
+#define CRISV17_IND_ADDC 6
#define CRISV10_IND_BOUND 7
#define CRISV10_IND_BCC_M 7
#define CRISV10_IND_MOVE_M_SPR 8
diff --git a/target-cris/translate.c b/target-cris/translate.c
index f4a8d7d000..b5ab0a5fb2 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -140,14 +140,14 @@ static void gen_BUG(DisasContext *dc, const char *file, int line)
cpu_abort(CPU(dc->cpu), "%s:%d\n", file, line);
}
-static const char *regnames[] =
+static const char *regnames_v32[] =
{
"$r0", "$r1", "$r2", "$r3",
"$r4", "$r5", "$r6", "$r7",
"$r8", "$r9", "$r10", "$r11",
"$r12", "$r13", "$sp", "$acr",
};
-static const char *pregnames[] =
+static const char *pregnames_v32[] =
{
"$bz", "$vr", "$pid", "$srs",
"$wz", "$exs", "$eda", "$mof",
@@ -3327,12 +3327,20 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
{
CRISCPU *cpu = CRIS_CPU(cs);
CPUCRISState *env = &cpu->env;
+ const char **regnames;
+ const char **pregnames;
int i;
- uint32_t srs;
if (!env || !f) {
return;
}
+ if (env->pregs[PR_VR] < 32) {
+ pregnames = pregnames_v10;
+ regnames = regnames_v10;
+ } else {
+ pregnames = pregnames_v32;
+ regnames = regnames_v32;
+ }
cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
"cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
@@ -3354,14 +3362,16 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "\n");
}
}
- srs = env->pregs[PR_SRS];
- cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
- if (srs < ARRAY_SIZE(env->sregs)) {
- for (i = 0; i < 16; i++) {
- cpu_fprintf(f, "s%2.2d=%8.8x ",
- i, env->sregs[srs][i]);
- if ((i + 1) % 4 == 0) {
- cpu_fprintf(f, "\n");
+ if (env->pregs[PR_VR] >= 32) {
+ uint32_t srs = env->pregs[PR_SRS];
+ cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
+ if (srs < ARRAY_SIZE(env->sregs)) {
+ for (i = 0; i < 16; i++) {
+ cpu_fprintf(f, "s%2.2d=%8.8x ",
+ i, env->sregs[srs][i]);
+ if ((i + 1) % 4 == 0) {
+ cpu_fprintf(f, "\n");
+ }
}
}
}
@@ -3406,12 +3416,12 @@ void cris_initialize_tcg(void)
for (i = 0; i < 16; i++) {
cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, regs[i]),
- regnames[i]);
+ regnames_v32[i]);
}
for (i = 0; i < 16; i++) {
cpu_PR[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUCRISState, pregs[i]),
- pregnames[i]);
+ pregnames_v32[i]);
}
}
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index 4707a18e77..4a0b485d8e 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -1094,6 +1094,29 @@ static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc)
insn_len = dec10_bdap_m(env, dc, size);
break;
default:
+ /*
+ * ADDC for v17:
+ *
+ * Instruction format: ADDC [Rs],Rd
+ *
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+
+ * |Destination(Rd)| 1 0 0 1 1 0 1 0 | Source(Rs)|
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+
+ *
+ * Instruction format: ADDC [Rs+],Rd
+ *
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+
+ * |Destination(Rd)| 1 1 0 1 1 0 1 0 | Source(Rs)|
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+
+ */
+ if (dc->opcode == CRISV17_IND_ADDC && dc->size == 2 &&
+ env->pregs[PR_VR] == 17) {
+ LOG_DIS("addc op=%d %d\n", dc->src, dc->dst);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ insn_len += dec10_ind_alu(env, dc, CC_OP_ADDC, size);
+ break;
+ }
+
LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
dc->pc, size, dc->opcode, dc->src, dc->dst);
cpu_abort(CPU(dc->cpu), "Unhandled opcode");
diff --git a/tests/tcg/cris/Makefile b/tests/tcg/cris/Makefile
index d34bfd8f7a..6b3dba446c 100644
--- a/tests/tcg/cris/Makefile
+++ b/tests/tcg/cris/Makefile
@@ -23,6 +23,7 @@ SYS = sys.o
TESTCASES += check_abs.tst
TESTCASES += check_addc.tst
TESTCASES += check_addcm.tst
+TESTCASES += check_addcv17.tst
TESTCASES += check_addo.tst
TESTCASES += check_addoq.tst
TESTCASES += check_addi.tst
@@ -108,14 +109,12 @@ TESTCASES += check_stat4.ctst
TESTCASES += check_openpf1.ctst
TESTCASES += check_openpf2.ctst
TESTCASES += check_openpf3.ctst
-TESTCASES += check_openpf4.ctst
TESTCASES += check_openpf5.ctst
TESTCASES += check_mapbrk.ctst
TESTCASES += check_mmap1.ctst
TESTCASES += check_mmap2.ctst
TESTCASES += check_mmap3.ctst
TESTCASES += check_sigalrm.ctst
-TESTCASES += check_time1.ctst
TESTCASES += check_time2.ctst
TESTCASES += check_settls1.ctst
@@ -136,13 +135,27 @@ all: build
%.ctst: %.o
$(CC) $(CFLAGS) $(LDLIBS) $< -o $@
+
+sysv10.o: sys.c
+ $(CC) $(CFLAGS) -mcpu=v10 -c $< -o $@
+
+crtv10.o: crt.s
+ $(AS) $(ASFLAGS) -mcpu=v10 -c $< -o $@
+
+check_addcv17.tst: ASFLAGS += -mcpu=v10
+check_addcv17.tst: CRT := crtv10.o
+check_addcv17.tst: SYS := sysv10.o
+check_addcv17.tst: crtv10.o sysv10.o
+
build: $(CRT) $(SYS) $(TESTCASES)
check: $(CRT) $(SYS) $(TESTCASES)
@echo -e "\nQEMU simulator."
for case in $(TESTCASES); do \
echo -n "$$case "; \
- $(SIM) ./$$case; \
+ SIMARGS=; \
+ case $$case in *v17*) SIMARGS="-cpu crisv17";; esac; \
+ $(SIM) $$SIMARGS ./$$case; \
done
check-g: $(CRT) $(SYS) $(TESTCASES)
@echo -e "\nGDB simulator."
@@ -152,4 +165,4 @@ check-g: $(CRT) $(SYS) $(TESTCASES)
done
clean:
- $(RM) -fr $(TESTCASES) $(CRT) $(SYS)
+ $(RM) -fr $(TESTCASES) *.o
diff --git a/tests/tcg/cris/check_abs.c b/tests/tcg/cris/check_abs.c
index 9770a8d9ef..08b67b6ef0 100644
--- a/tests/tcg/cris/check_abs.c
+++ b/tests/tcg/cris/check_abs.c
@@ -4,14 +4,14 @@
#include "sys.h"
#include "crisutils.h"
-static inline int cris_abs(int n)
+static always_inline int cris_abs(int n)
{
int r;
asm ("abs\t%1, %0\n" : "=r" (r) : "r" (n));
return r;
}
-static inline void
+static always_inline void
verify_abs(int val, int res,
const int n, const int z, const int v, const int c)
{
diff --git a/tests/tcg/cris/check_addc.c b/tests/tcg/cris/check_addc.c
index facd1bea2d..fc3fb1faa8 100644
--- a/tests/tcg/cris/check_addc.c
+++ b/tests/tcg/cris/check_addc.c
@@ -4,7 +4,7 @@
#include "sys.h"
#include "crisutils.h"
-static inline int cris_addc(int a, const int b)
+static always_inline int cris_addc(int a, const int b)
{
asm ("addc\t%1, %0\n" : "+r" (a) : "r" (b));
return a;
diff --git a/tests/tcg/cris/check_addcm.c b/tests/tcg/cris/check_addcm.c
index 7928bc9999..b355ba164f 100644
--- a/tests/tcg/cris/check_addcm.c
+++ b/tests/tcg/cris/check_addcm.c
@@ -5,14 +5,14 @@
#include "crisutils.h"
/* need to avoid acr as source here. */
-static inline int cris_addc_m(int a, const int *b)
+static always_inline int cris_addc_m(int a, const int *b)
{
asm volatile ("addc [%1], %0\n" : "+r" (a) : "r" (b));
return a;
}
/* 'b' is a crisv32 constrain to avoid postinc with $acr. */
-static inline int cris_addc_pi_m(int a, int **b)
+static always_inline int cris_addc_pi_m(int a, int **b)
{
asm volatile ("addc [%1+], %0\n" : "+r" (a), "+b" (*b));
return a;
diff --git a/tests/tcg/cris/check_addcv17.s b/tests/tcg/cris/check_addcv17.s
new file mode 100644
index 0000000000..52ef7a9716
--- /dev/null
+++ b/tests/tcg/cris/check_addcv17.s
@@ -0,0 +1,65 @@
+# mach: crisv17
+
+ .include "testutils.inc"
+
+ .macro addc Rs Rd inc=0
+# Create the instruction manually since there is no assembler support yet
+ .word (\Rd << 12) | \Rs | (\inc << 10) | 0x09a0
+ .endm
+
+ start
+
+ .data
+mem1:
+ .dword 0x0
+mem2:
+ .dword 0x12345678
+
+ .text
+ move.d mem1,r4
+ clearf nzvc
+ addc 4 3
+ test_cc 0 1 0 0
+ checkr3 0
+
+ move.d mem1,r4
+ clearf nzvc
+ ax
+ addc 4 3
+ test_cc 0 0 0 0
+ checkr3 0
+
+ move.d mem1,r4
+ clearf nzvc
+ setf c
+ addc 4 3
+ test_cc 0 0 0 0
+ checkr3 1
+
+ move.d mem2,r4
+ moveq 2, r3
+ clearf nzvc
+ setf c
+ addc 4 3
+ test_cc 0 0 0 0
+ checkr3 1234567b
+
+ move.d mem2,r5
+ clearf nzvc
+ cmp.d r4,r5
+ test_cc 0 1 0 0
+
+ move.d mem2,r4
+ moveq 2, r3
+ clearf nzvc
+ addc 4 3 inc=1
+ test_cc 0 0 0 0
+ checkr3 1234567a
+
+ move.d mem2,r5
+ clearf nzvc
+ addq 4,r5
+ cmp.d r4,r5
+ test_cc 0 1 0 0
+
+ quit
diff --git a/tests/tcg/cris/check_bound.c b/tests/tcg/cris/check_bound.c
index e8831754ec..d956ab9ade 100644
--- a/tests/tcg/cris/check_bound.c
+++ b/tests/tcg/cris/check_bound.c
@@ -4,21 +4,21 @@
#include "sys.h"
#include "crisutils.h"
-static inline int cris_bound_b(int v, int b)
+static always_inline int cris_bound_b(int v, int b)
{
int r = v;
asm ("bound.b\t%1, %0\n" : "+r" (r) : "ri" (b));
return r;
}
-static inline int cris_bound_w(int v, int b)
+static always_inline int cris_bound_w(int v, int b)
{
int r = v;
asm ("bound.w\t%1, %0\n" : "+r" (r) : "ri" (b));
return r;
}
-static inline int cris_bound_d(int v, int b)
+static always_inline int cris_bound_d(int v, int b)
{
int r = v;
asm ("bound.d\t%1, %0\n" : "+r" (r) : "ri" (b));
diff --git a/tests/tcg/cris/check_ftag.c b/tests/tcg/cris/check_ftag.c
index 908773a38a..aaa5c97115 100644
--- a/tests/tcg/cris/check_ftag.c
+++ b/tests/tcg/cris/check_ftag.c
@@ -4,22 +4,22 @@
#include "sys.h"
#include "crisutils.h"
-static inline void cris_ftag_i(unsigned int x)
+static always_inline void cris_ftag_i(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("ftagi\t[%0]\n" : : "r" (v) );
}
-static inline void cris_ftag_d(unsigned int x)
+static always_inline void cris_ftag_d(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("ftagd\t[%0]\n" : : "r" (v) );
}
-static inline void cris_fidx_i(unsigned int x)
+static always_inline void cris_fidx_i(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("fidxi\t[%0]\n" : : "r" (v) );
}
-static inline void cris_fidx_d(unsigned int x)
+static always_inline void cris_fidx_d(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("fidxd\t[%0]\n" : : "r" (v) );
diff --git a/tests/tcg/cris/check_int64.c b/tests/tcg/cris/check_int64.c
index fc600176e2..69caec1bb2 100644
--- a/tests/tcg/cris/check_int64.c
+++ b/tests/tcg/cris/check_int64.c
@@ -5,12 +5,12 @@
#include "crisutils.h"
-static inline int64_t add64(const int64_t a, const int64_t b)
+static always_inline int64_t add64(const int64_t a, const int64_t b)
{
return a + b;
}
-static inline int64_t sub64(const int64_t a, const int64_t b)
+static always_inline int64_t sub64(const int64_t a, const int64_t b)
{
return a - b;
}
diff --git a/tests/tcg/cris/check_lz.c b/tests/tcg/cris/check_lz.c
index 69c2e6d4ec..bf051a6b55 100644
--- a/tests/tcg/cris/check_lz.c
+++ b/tests/tcg/cris/check_lz.c
@@ -3,7 +3,7 @@
#include <stdint.h>
#include "sys.h"
-static inline int cris_lz(int x)
+static always_inline int cris_lz(int x)
{
int r;
asm ("lz\t%1, %0\n" : "=r" (r) : "r" (x));
diff --git a/tests/tcg/cris/check_openpf4.c b/tests/tcg/cris/check_openpf4.c
deleted file mode 100644
index 8bbee41a64..0000000000
--- a/tests/tcg/cris/check_openpf4.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Basic file operations, now *with* sysroot.
-#sim: --sysroot=@exedir@
-*/
-#define PREFIX "/"
-#include "check_openpf3.c"
diff --git a/tests/tcg/cris/check_swap.c b/tests/tcg/cris/check_swap.c
index f851cbcef1..9a68c1e5d7 100644
--- a/tests/tcg/cris/check_swap.c
+++ b/tests/tcg/cris/check_swap.c
@@ -9,7 +9,7 @@
#define B 2
#define R 1
-static inline int cris_swap(const int mode, int x)
+static always_inline int cris_swap(const int mode, int x)
{
switch (mode)
{
diff --git a/tests/tcg/cris/check_time1.c b/tests/tcg/cris/check_time1.c
deleted file mode 100644
index 3fcf0e1535..0000000000
--- a/tests/tcg/cris/check_time1.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Basic time functionality test: check that milliseconds are
- incremented for each syscall (does not work on host). */
-#include <stdio.h>
-#include <time.h>
-#include <sys/time.h>
-#include <string.h>
-#include <stdlib.h>
-
-void err (const char *s)
-{
- perror (s);
- abort ();
-}
-
-int
-main (void)
-{
- struct timeval t_m = {0, 0};
- struct timezone t_z = {0, 0};
- struct timeval t_m1 = {0, 0};
- int i;
-
- if (gettimeofday (&t_m, &t_z) != 0)
- err ("gettimeofday");
-
- for (i = 1; i < 10000; i++)
- if (gettimeofday (&t_m1, NULL) != 0)
- err ("gettimeofday 1");
- else
- if (t_m1.tv_sec * 1000000 + t_m1.tv_usec
- != (t_m.tv_sec * 1000000 + t_m.tv_usec + i * 1000))
- {
- fprintf (stderr, "t0 (%ld, %ld), i %d, t1 (%ld, %ld)\n",
- t_m.tv_sec, t_m.tv_usec, i, t_m1.tv_sec, t_m1.tv_usec);
- abort ();
- }
-
- if (time (NULL) != t_m1.tv_sec)
- {
- fprintf (stderr, "time != gettod\n");
- abort ();
- }
-
- printf ("pass\n");
- exit (0);
-}
diff --git a/tests/tcg/cris/crisutils.h b/tests/tcg/cris/crisutils.h
index 3456b9d50d..bbbe6c5540 100644
--- a/tests/tcg/cris/crisutils.h
+++ b/tests/tcg/cris/crisutils.h
@@ -13,57 +13,57 @@ void _err(void) {
_fail(tst_cc_loc);
}
-static inline void cris_tst_cc_n1(void)
+static always_inline void cris_tst_cc_n1(void)
{
asm volatile ("bpl _err\n"
"nop\n");
}
-static inline void cris_tst_cc_n0(void)
+static always_inline void cris_tst_cc_n0(void)
{
asm volatile ("bmi _err\n"
"nop\n");
}
-static inline void cris_tst_cc_z1(void)
+static always_inline void cris_tst_cc_z1(void)
{
asm volatile ("bne _err\n"
"nop\n");
}
-static inline void cris_tst_cc_z0(void)
+static always_inline void cris_tst_cc_z0(void)
{
asm volatile ("beq _err\n"
"nop\n");
}
-static inline void cris_tst_cc_v1(void)
+static always_inline void cris_tst_cc_v1(void)
{
asm volatile ("bvc _err\n"
"nop\n");
}
-static inline void cris_tst_cc_v0(void)
+static always_inline void cris_tst_cc_v0(void)
{
asm volatile ("bvs _err\n"
"nop\n");
}
-static inline void cris_tst_cc_c1(void)
+static always_inline void cris_tst_cc_c1(void)
{
asm volatile ("bcc _err\n"
"nop\n");
}
-static inline void cris_tst_cc_c0(void)
+static always_inline void cris_tst_cc_c0(void)
{
asm volatile ("bcs _err\n"
"nop\n");
}
-static inline void cris_tst_mov_cc(int n, int z)
+static always_inline void cris_tst_mov_cc(int n, int z)
{
if (n) cris_tst_cc_n1(); else cris_tst_cc_n0();
if (z) cris_tst_cc_z1(); else cris_tst_cc_z0();
asm volatile ("" : : "g" (_err));
}
-static inline void cris_tst_cc(const int n, const int z,
+static always_inline void cris_tst_cc(const int n, const int z,
const int v, const int c)
{
if (n) cris_tst_cc_n1(); else cris_tst_cc_n0();
diff --git a/tests/tcg/cris/sys.c b/tests/tcg/cris/sys.c
index 551c5dd7cb..21f08c0747 100644
--- a/tests/tcg/cris/sys.c
+++ b/tests/tcg/cris/sys.c
@@ -33,19 +33,27 @@ void *memset (void *s, int c, size_t n) {
}
void exit (int status) {
- asm volatile ("moveq 1, $r9\n" /* NR_exit. */
- "break 13\n");
+ register unsigned int callno asm ("r9") = 1; /* NR_exit */
+
+ asm volatile ("break 13\n"
+ :
+ : "r" (callno)
+ : "memory" );
while(1)
;
}
ssize_t write (int fd, const void *buf, size_t count) {
- int r;
- asm ("move.d %0, $r10\n"
- "move.d %1, $r11\n"
- "move.d %2, $r12\n"
- "moveq 4, $r9\n" /* NR_write. */
- "break 13\n" : : "r" (fd), "r" (buf), "r" (count) : "memory");
- asm ("move.d $r10, %0\n" : "=r" (r));
+ register unsigned int callno asm ("r9") = 4; /* NR_write */
+ register unsigned int r10 asm ("r10") = fd;
+ register const void *r11 asm ("r11") = buf;
+ register size_t r12 asm ("r12") = count;
+ register unsigned int r asm ("r10");
+
+ asm volatile ("break 13\n"
+ : "=r" (r)
+ : "r" (callno), "0" (r10), "r" (r11), "r" (r12)
+ : "memory");
+
return r;
}
diff --git a/tests/tcg/cris/sys.h b/tests/tcg/cris/sys.h
index c5f88e1a29..3dd47bb673 100644
--- a/tests/tcg/cris/sys.h
+++ b/tests/tcg/cris/sys.h
@@ -3,6 +3,8 @@
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
+#define always_inline inline __attribute__((always_inline))
+
#define CURRENT_LOCATION __FILE__ ":" TOSTRING(__LINE__)
#define err() \