Merge commit '57999ac9b9d32775efc271e0edfed27b784ee1c6' as 'parallel-rsp'

This commit is contained in:
Logan McNaughton committed 2020-10-31 15:49:56 -06:00
commit d9155d3878
377 files changed
+137898

No files matched your search

@@ -0,0 +1,20 @@
#
# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
# GNU lightning is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU lightning 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 Lesser General Public
# License for more details.
#
SUBDIRS = \
lightning
nodist_include_HEADERS = lightning.h
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,65 @@
#
# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
# GNU lightning is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU lightning 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 Lesser General Public
# License for more details.
#
lightning_includedir = $(includedir)/lightning
EXTRA_DIST = \
jit_private.h
if cpu_arm
lightning_include_HEADERS = \
jit_arm.h
endif
if cpu_mips
lightning_include_HEADERS = \
jit_mips.h
endif
if cpu_ppc
lightning_include_HEADERS = \
jit_ppc.h
endif
if cpu_sparc
lightning_include_HEADERS = \
jit_sparc.h
endif
if cpu_x86
lightning_include_HEADERS = \
jit_x86.h
endif
if cpu_ia64
lightning_include_HEADERS = \
jit_ia64.h
endif
if cpu_hppa
lightning_include_HEADERS = \
jit_hppa.h
endif
if cpu_aarch64
lightning_include_HEADERS = \
jit_aarch64.h
endif
if cpu_s390
lightning_include_HEADERS = \
jit_s390.h
endif
if cpu_alpha
lightning_include_HEADERS = \
jit_alpha.h
endif
if cpu_riscv
lightning_include_HEADERS = \
jit_riscv.h
endif
@@ -0,0 +1,89 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_aarch64_h
#define _jit_aarch64_h
#define JIT_HASH_CONSTS 0
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
#define JIT_FP _R29
typedef enum {
#define jit_r(i) (_R9 + (i))
#define jit_r_num() 7
#define jit_v(i) (_R19 + (i))
#define jit_v_num() 10
#define jit_f(i) (_V8 + (i))
#define jit_f_num() 8
#define JIT_R0 _R9
#define JIT_R1 _R10
#define JIT_R2 _R11
#define JIT_R3 _R12
#define JIT_R4 _R13
#define JIT_R5 _R14
#define JIT_R6 _R15
_R8, /* indirect result */
_R18, /* platform register */
_R17, /* IP1 */
_R16, /* IP0 */
_R9, _R10, _R11, _R12, /* temporaries */
_R13, _R14, _R15,
#define JIT_V0 _R19
#define JIT_V1 _R20
#define JIT_V2 _R21
#define JIT_V3 _R22
#define JIT_V4 _R23
#define JIT_V5 _R24
#define JIT_V6 _R25
#define JIT_V7 _R26
#define JIT_V8 _R27
#define JIT_V9 _R28
_R19, _R20, _R21, _R22, /* callee save */
_R23, _R24, _R25, _R26,
_R27, _R28,
_SP, /* stack pointer */
_R30, /* link register */
_R29, /* frame pointer */
_R7, _R6, _R5, _R4,
_R3, _R2, _R1, _R0,
#define JIT_F0 _V8
#define JIT_F1 _V9
#define JIT_F2 _V10
#define JIT_F3 _V11
#define JIT_F4 _V12
#define JIT_F5 _V13
#define JIT_F6 _V14
#define JIT_F7 _V15
_V31, _V30, _V29, _V28, /* temporaries */
_V27, _V26, _V25, _V24,
_V23, _V22, _V21, _V20,
_V19, _V18, _V17, _V16,
/* callee save */
_V8, _V9, _V10, _V11,
_V12, _V13, _V14, _V15,
_V7, _V6, _V5, _V4, /* arguments */
_V3, _V2, _V1, _V0,
_NOREG,
#define JIT_NOREG _NOREG
} jit_reg_t;
#endif /* _jit_aarch64_h */
@@ -0,0 +1,105 @@
/*
* Copyright (C) 2014-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_alpha_h
#define _jit_alpha_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
#define JIT_FP _FP
typedef enum {
#define jit_r(i) (_S0 + (i))
#define jit_r_num() 3
#define jit_v(i) (_S3 + (i))
#define jit_v_num() 3
#define jit_f(i) (_F2 + (i))
#define jit_f_num() 8
/* Volatile - Assembly temporary register */
_AT,
/* Volatile - Return value register */
_V0,
/* Volatile - Temporary registers */
_T0, _T1, _T2, _T3,
_T4, _T5, _T6, _T7,
_T8, _T9, _T10, _T11,
/* FIXME Use callee save register for r0-r2 (instead of 12+ JIT_RN
* and 6 JIT_VN because division must call a function)
* FIX would be to create proper functions that do not clobber
* registers and inject/inline them in the jit */
#define JIT_R0 _S0
#define JIT_R1 _S1
#define JIT_R2 _S2
#define JIT_V0 _S3
#define JIT_V1 _S4
#define JIT_V2 _S5
/* Nonvolatile - Saved registers */
_S0, _S1, _S2, _S3,
_S4, _S5,
/* Nonvolatile - Frame pointer */
_FP,
/* Volatile - Argument registers */
_A5, _A4, _A3, _A2,
_A1, _A0,
/* Volatile - Return address register */
_RA,
/* Volatile - Temporary register */
_PV,
/* Nonvolatile - Global pointer */
_GP,
/* Nonvolatile - Stack pointer */
_SP,
/* Constant RAZ / writes ignored */
_ZERO,
#define JIT_F0 _F2
#define JIT_F1 _F3
#define JIT_F2 _F4
#define JIT_F3 _F5
#define JIT_F4 _F6
#define JIT_F5 _F7
#define JIT_F6 _F8
#define JIT_F7 _F9
/* Volatile - Return value register (real part) */
_F0,
/* Volatile - Return value register (imaginary part) */
_F1,
/* Nonvolatile - Saved registers */
_F2, _F3, _F4, _F5,
_F6, _F7, _F8, _F9,
/* Volatile - Temporary registers */
_F10, _F11, _F12, _F13,
_F14, _F15,
/* Volatile - Argument registers */
_F21, _F20, _F19, _F18,
_F17, _F16,
/* Volatile - Temporary registers */
_F22, _F23, _R24, _F25,
_F26, _F27, _F28, _F29,
_F30,
/* Constant - RAZ / writes ignored */
_F31,
/* Lightning internal invalid register identifier */
_NOREG,
#define JIT_NOREG _NOREG
} jit_reg_t;
#endif /* _jit_alpha_h */
@@ -0,0 +1,127 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_arm_h
#define _jit_arm_h
#define JIT_HASH_CONSTS 0
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
#define jit_swf_p() (jit_cpu.vfp == 0)
#define jit_hardfp_p() jit_cpu.abi
#define jit_ldrt_strt_p() jit_cpu.ldrt_strt
#define JIT_FP _R11
typedef enum {
#define jit_r(i) (_R4 + (i))
#define jit_r_num() 3
#define jit_v(i) (_R7 + (i))
#define jit_v_num() 3
#define jit_f(i) (jit_cpu.abi ? _D8 + ((i)<<1) : _D0 - ((i)<<1))
#define jit_f_num() 8
_R12, /* ip - temporary */
#define JIT_R0 _R4
#define JIT_R1 _R5
#define JIT_R2 _R6
_R4, /* r4 - variable */
_R5, /* r5 - variable */
_R6, /* r6 - variable */
#define JIT_V0 _R7
#define JIT_V1 _R8
#define JIT_V2 _R9
_R7, /* r7 - variable */
_R8, /* r8 - variable */
_R9, /* r9 - variable */
_R10, /* sl - stack limit */
_R11, /* fp - frame pointer */
_R13, /* sp - stack pointer */
_R14, /* lr - link register */
_R15, /* pc - program counter */
_R3, /* r3 - argument/result */
_R2, /* r2 - argument/result */
_R1, /* r1 - argument/result */
_R0, /* r0 - argument/result */
#define JIT_F0 (jit_hardfp_p() ? _D8 : _D0)
#define JIT_F1 (jit_hardfp_p() ? _D9 : _D1)
#define JIT_F2 (jit_hardfp_p() ? _D10 : _D2)
#define JIT_F3 (jit_hardfp_p() ? _D11 : _D3)
#define JIT_F4 (jit_hardfp_p() ? _D12 : _D4)
#define JIT_F5 (jit_hardfp_p() ? _D13 : _D5)
#define JIT_F6 (jit_hardfp_p() ? _D14 : _D6)
#define JIT_F7 (jit_hardfp_p() ? _D15 : _D7)
_S16, _D8 = _S16, _Q4 = _D8,
_S17,
_S18, _D9 = _S18,
_S19,
_S20, _D10 = _S20, _Q5 = _D10,
_S21,
_S22, _D11 = _S22,
_S23,
_S24, _D12 = _S24, _Q6 = _D12,
_S25,
_S26, _D13 = _S26,
_S27,
_S28, _D14 = _S28, _Q7 = _D14,
_S29,
_S30, _D15 = _S30,
_S31,
_S15,
_S14, _D7 = _S14,
_S13,
_S12, _D6 = _S12, _Q3 = _D6,
_S11,
_S10, _D5 = _S10,
_S9,
_S8, _D4 = _S8, _Q2 = _D4,
_S7,
_S6, _D3 = _S6,
_S5,
_S4, _D2 = _S4, _Q1 = _D2,
_S3,
_S2, _D1 = _S2,
_S1,
_S0, _D0 = _S0, _Q0 = _D0,
_NOREG,
#define JIT_NOREG _NOREG
} jit_reg_t;
typedef struct {
jit_uint32_t version : 4;
jit_uint32_t extend : 1;
/* only generate thumb instructions for thumb2 */
jit_uint32_t thumb : 1;
jit_uint32_t vfp : 3;
jit_uint32_t neon : 1;
jit_uint32_t abi : 2;
/* use strt+offset instead of str.w?
* on special cases it causes a SIGILL at least on qemu, probably
* due to some memory ordering constraint not being respected, so,
* disable by default */
jit_uint32_t ldrt_strt : 1;
} jit_cpu_t;
/*
* Initialization
*/
extern jit_cpu_t jit_cpu;
#endif /* _jit_arm_h */
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_hppa_h
#define _jit_hppa_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
typedef enum {
_R0, /* Always zero */
_R1, /* ADDIL implicit target */
_R2, /* B,L implicit target */
#define jit_r_num() 4
#define jit_r(n) ((n) < 3 ? _R4 + (n) : _R10 + (n) - 3)
#define jit_v_num() 11
#define jit_v(n) ((n) < 3 ? _R7 + (n) : _R11 + (n) - 3)
#define jit_f_num() 8
#define jit_f(n) (_F12 - (n))
#define JIT_FP _R3
#define JIT_R0 _R4
#define JIT_R1 _R5
#define JIT_R2 _R6
#define JIT_R3 _R10
#define JIT_V0 _R7
#define JIT_V1 _R8
#define JIT_V2 _R9
#define JIT_V3 _R11
#define JIT_V4 _R12
#define JIT_V5 _R13
#define JIT_V6 _R14
#define JIT_V7 _R15
#define JIT_V8 _R16
#define JIT_V9 _R17
#define JIT_V10 _R18
_R3,
_R19,
_R20,
_R21,
_R22,
_R29, /* ret1 */
_R28, /* ret0 */
_R4,
_R5,
_R6,
_R7,
_R8,
_R9,
_R10,
_R11,
_R12,
_R13,
_R14,
_R15,
_R16,
_R17,
_R18,
_R23, /* arg3 */
_R24, /* arg2 */
_R25, /* arg1 */
_R26, /* arg0 */
_R27, /* Data Pointer */
_R30, /* Stack Pointer */
_R31, /* Link register */
#define JIT_F0 _F12
#define JIT_F1 _F13
#define JIT_F2 _F14
#define JIT_F3 _F15
#define JIT_F4 _F16
#define JIT_F5 _F17
#define JIT_F6 _F18
#define JIT_F7 _F19
#define JIT_F8 _F20
#define JIT_F9 _F21
/* Caller Saves */
_F31,
_F30,
_F29,
_F28,
_F27,
_F26,
_F25,
_F24,
_F23,
_F22,
_F11,
_F10,
_F9,
_F8,
/* Arguments */
_F7, /* farg3 */
_F6, /* farg2 */
_F5, /* farg1 */
_F4, /* farg0 */
/* Callee Saves */
_F21,
_F20,
_F19,
_F18,
_F17,
_F16,
_F15,
_F14,
_F13,
_F12,
/* Floating-Pointer Status and Exception */
_F0,
_F1,
_F2,
_F3,
#define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;
#endif /* _jit_hppa */
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_ia64_h
#define _jit_ia64_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
#define JIT_FP _R4 /* Not abi specific */
typedef enum {
#define JIT_R0 _R40
#define JIT_R1 _R41
#define JIT_R2 _R42
#define JIT_R3 _R43
#define JIT_V0 _R44
#define JIT_V1 _R45
#define JIT_V2 _R46
#define JIT_V3 _R47
#define jit_r_num() 4
#define jit_r(n) (_R40 + (n))
#define jit_v_num() 4
#define jit_v(n) (_R44 + (n))
_R0, /* constant - Always 0 */
_R1, /* special - Global Data pointer (gp) */
/* r2-r3 - scratch - Use with 22-bit immediate add - scratch */
_R2, _R3,
/* r4-r7 - preserved */
_R4, _R5, _R6, _R7,
_R8, /* scratch - Return value; structure/union return pointer */
/* r9-r11 - scratch - Return values */
_R9, _R10, _R11,
_R12, /* special - Memory stack pointer (sp) */
_R13, /* special - Reserved as a thread pointer (tp)*/
/* r14-r31 - scratch */
_R31, _R30,
_R29, _R28, _R27, _R26, _R25, _R24, _R23, _R22,
_R21, _R20, _R19, _R18, _R17, _R16, _R15, _R14,
/* r32-r39 - aka in0-in7 - Incoming register arguments */
_R32, _R33, _R34, _R35, _R36, _R37, _R38, _R39,
/* r40-r127 - loc0...locn,out0...outn */
_R40, _R41, _R42, _R43, _R44, _R45, _R46, _R47,
_R48, _R49, _R50, _R51, _R52, _R53, _R54, _R55,
_R56, _R57, _R58, _R59, _R60, _R61, _R62, _R63,
_R64, _R65, _R66, _R67, _R68, _R69, _R70, _R71,
_R72, _R73, _R74, _R75, _R76, _R77, _R78, _R79,
_R80, _R81, _R82, _R83, _R84, _R85, _R86, _R87,
_R88, _R89, _R90, _R91, _R92, _R93, _R94, _R95,
_R96, _R97, _R98, _R99, _R100, _R101, _R102, _R103,
_R104, _R105, _R106, _R107, _R108, _R109, _R110, _R111,
_R112, _R113, _R114, _R115, _R116, _R117, _R118, _R119,
_R120, _R121, _R122, _R123, _R124, _R125, _R126, _R127,
#define JIT_F0 _F16
#define JIT_F1 _F17
#define JIT_F2 _F18
#define JIT_F3 _F19
#define JIT_F4 _F20
#define JIT_F5 _F21
#define jit_f_num() 6
#define jit_f(n) (_F16 + (n))
_F0, /* constant - Always 0.0 */
_F1, /* constant - Always 1.0 */
/* f2-f5 - preserved */
_F2, _F3, _F4, _F5,
/* f6-f7 - scratch */
_F6, _F7,
/* f8-f15 - scratch - Argument/return registers */
_F8, _F9, _F10, _F11, _F12, _F13, _F14, _F15,
/* f16-f31 - preserved */
_F16, _F17, _F18, _F19, _F20, _F21, _F22, _F23,
_F24, _F25, _F26, _F27, _F28, _F29, _F30, _F31,
/* f32-f127 - scratch - Rotating registers or scratch */
_F32, _F33, _F34, _F35, _F36, _F37, _F38, _F39,
_F40, _F41, _F42, _F43, _F44, _F45, _F46, _F47,
_F48, _F49, _F50, _F51, _F52, _F53, _F54, _F55,
_F56, _F57, _F58, _F59, _F60, _F61, _F62, _F63,
_F64, _F65, _F66, _F67, _F68, _F69, _F70, _F71,
_F72, _F73, _F74, _F75, _F76, _F77, _F78, _F79,
_F80, _F81, _F82, _F83, _F84, _F85, _F86, _F87,
_F88, _F89, _F90, _F91, _F92, _F93, _F94, _F95,
_F96, _F97, _F98, _F99, _F100, _F101, _F102, _F103,
_F104, _F105, _F106, _F107, _F108, _F109, _F110, _F111,
_F112, _F113, _F114, _F115, _F116, _F117, _F118, _F119,
#if 0
/* Do not list these to not need an unique identifier larger
* than 255 for jit_regset_t */
_F120, _F121, _F122, _F123, _F124, _F125, _F126, _F127,
#endif
/* Fake registers. Required because while "in" parameters start at r32,
* "out" parameters start *after* registers allocated for temporaries,
* and that are supposed to kept alive (what is desirable, that is, to
* not spill/reload them in memory) */
_OUT0, _OUT1, _OUT2, _OUT3, _OUT4, _OUT5, _OUT6, _OUT7,
#define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;
#endif /* _jit_ia64_h */
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_mips_h
#define _jit_mips_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
#if _MIPS_SIM != _ABIO32
# define NEW_ABI 1
#endif
/*
* Types
*/
#define JIT_FP _FP
typedef enum {
#define jit_r(i) (_V0 + (i))
#if NEW_ABI
# define jit_r_num() 7
#else
# define jit_r_num() 11
#endif
#define jit_v(i) (_S0 + (i))
#define jit_v_num() 8
#define jit_f(i) (_F0 + (i))
#if NEW_ABI
# define jit_f_num() 6
#else
# define jit_f_num() 8
#endif
_AT,
#define JIT_R0 _V0
#define JIT_R1 _V1
#if NEW_ABI
# define JIT_R2 _T4
# define JIT_R3 _T5
# define JIT_R4 _T6
# define JIT_R5 _T7
# define JIT_R6 _T8
#else
# define JIT_R2 _T0
# define JIT_R3 _T1
# define JIT_R4 _T2
# define JIT_R5 _T3
# define JIT_R6 _T4
# define JIT_R7 _T5
# define JIT_R8 _T6
# define JIT_R9 _T7
# define JIT_R10 _T8
#endif
_V0, _V1,
#if !NEW_ABI
_T0, _T1, _T2, _T3,
#endif
_T4, _T5, _T6, _T7, _T8, _T9,
#define JIT_V0 _S0
#define JIT_V1 _S1
#define JIT_V2 _S2
#define JIT_V3 _S3
#define JIT_V4 _S4
#define JIT_V5 _S5
#define JIT_V6 _S6
#define JIT_V7 _S7
_S0, _S1, _S2, _S3, _S4, _S5, _S6, _S7,
_ZERO, _K0, _K1, _RA,
_GP,
_SP, _FP,
#if NEW_ABI
_A7, _A6, _A5, _A4,
#endif
_A3, _A2, _A1, _A0,
#define JIT_F0 _F0
#define JIT_F1 _F2
#define JIT_F2 _F4
#define JIT_F3 _F6
#define JIT_F4 _F8
#define JIT_F5 _F10
#if !NEW_ABI
# define JIT_F6 _F16
# define JIT_F7 _F18
#endif
_F0, _F2, _F4, _F6, _F8, _F10,
/* callee save float registers */
#if !NEW_ABI
_F16, _F18,
#endif
_F20, _F22, _F24, _F26, _F28, _F30,
#if NEW_ABI
_F19, _F18, _F17, _F16, _F15, _F14, _F13, _F12,
#else
_F14, _F12,
#endif
#define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;
#endif /* _jit_mips_h */
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_ppc_h
#define _jit_ppc_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
typedef enum {
#define jit_r(i) (_R28 + (i))
#define jit_r_num() 3
#define jit_v(i) (_R27 - (i))
#define jit_v_num() 14
#define jit_f(i) (_F14 + (i))
#define jit_f_num() 8
_R0,
#define JIT_R0 _R28
#define JIT_R1 _R29
#define JIT_R2 _R30
_R11, _R12, _R13, _R2,
#define JIT_V0 jit_v(0)
#define JIT_V1 jit_v(1)
#define JIT_V2 jit_v(2)
#define JIT_V3 jit_v(3)
#define JIT_V4 jit_v(4)
#define JIT_V5 jit_v(5)
#define JIT_V6 jit_v(6)
#define JIT_V7 jit_v(7)
#define JIT_V8 jit_v(8)
#define JIT_V9 jit_v(9)
#define JIT_V10 jit_v(10)
#define JIT_V11 jit_v(11)
#define JIT_V12 jit_v(12)
#define JIT_V13 jit_v(13)
_R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21,
_R22, _R23, _R24, _R25, _R26, _R27, _R28, _R29,
_R30,
_R1,
#define JIT_FP _R31
_R31,
_R10, _R9, _R8, _R7, _R6, _R5, _R4, _R3,
_F0,
_F14, _F15, _F16, _F17, _F18, _F19, _F20, _F21,
#define JIT_F0 _F14
#define JIT_F1 _F15
#define JIT_F2 _F16
#define JIT_F3 _F17
#define JIT_F4 _F18
#define JIT_F5 _F19
#define JIT_F6 _F20
#define JIT_F7 _F21
/* FIXME _F20-_F31 not (easily) accessible and only _F14-_F21
* saved/restored (if used) */
_F22, _F23, _F24, _F25, _F26, _F27, _F28, _F29,
_F30, _F31,
_F13, _F12, _F11, _F10, _F9, _F8, _F7, _F6,
_F5, _F4, _F3, _F2, _F1,
_NOREG,
#define JIT_NOREG _NOREG
} jit_reg_t;
#endif /* _jit_ppc_h */
@@ -0,0 +1,773 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_private_h
#define _jit_private_h
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stddef.h>
#else
# if !defined(offsetof)
# define offsetof(type, field) ((char *)&((type *)0)->field - (char *)0)
# endif
#endif
#if defined(__GNUC__)
# define maybe_unused __attribute__ ((unused))
# define unlikely(exprn) __builtin_expect(!!(exprn), 0)
# define likely(exprn) __builtin_expect(!!(exprn), 1)
# if (__GNUC__ >= 4)
# define PUBLIC __attribute__ ((visibility("default")))
# define HIDDEN __attribute__ ((visibility("hidden")))
# else
# define PUBLIC /**/
# define HIDDEN /**/
# endif
#else
# define maybe_unused /**/
# define unlikely(exprn) exprn
# define likely(exprn) exprn
# define PUBLIC /**/
# define HIDDEN /**/
#endif
#define rc(value) jit_class_##value
#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec))
#if defined(__i386__) || defined(__x86_64__)
# define JIT_SP _RSP
# define JIT_RET _RAX
# if __X32
# define JIT_FRET _ST0
typedef jit_uint32_t jit_regset_t;
# else
# if __CYGWIN__ || _WIN32
# define JIT_RA0 _RCX
# else
# define JIT_RA0 _RDI
# endif
# define JIT_FA0 _XMM0
# define JIT_FRET _XMM0
typedef jit_uint64_t jit_regset_t;
# endif
#elif defined(__mips__)
# define JIT_RA0 _A0
# define JIT_FA0 _F12
# define JIT_SP _SP
# define JIT_RET _V0
# define JIT_FRET _F0
typedef jit_uint64_t jit_regset_t;
#elif defined(__arm__)
# define JIT_RA0 _R0
# define JIT_FA0 _D0
# define JIT_SP _R13
# define JIT_RET _R0
# if defined(__ARM_PCS_VFP)
# define JIT_FRET _D0
# else
# define JIT_FRET _R0
# endif
typedef jit_uint64_t jit_regset_t;
#elif defined(__powerpc__)
# define JIT_RA0 _R3
# define JIT_FA0 _F1
# define JIT_SP _R1
# define JIT_RET _R3
# define JIT_FRET _F1
typedef jit_uint64_t jit_regset_t;
#elif defined(__sparc__)
# define JIT_SP _SP
# define JIT_RET _I0
# define JIT_FRET _F0
# if __WORDSIZE == 32
typedef jit_uint64_t jit_regset_t;
# else
typedef struct {
jit_uint64_t rl;
jit_uint64_t rh;
} jit_regset_t;
# endif
#elif defined(__ia64__)
# define JIT_SP _R12
# define JIT_RET _R8
# define JIT_FRET _F8
typedef struct {
jit_uint64_t rl;
jit_uint64_t rh;
jit_uint64_t fl;
jit_uint64_t fh;
} jit_regset_t;
#elif defined(__hppa__)
# define JIT_SP _R30
# define JIT_RET _R28
# define JIT_FRET _F4
typedef jit_uint64_t jit_regset_t;
#elif defined(__aarch64__)
# define JIT_RA0 _R0
# define JIT_FA0 _V0
# define JIT_SP _SP
# define JIT_RET _R0
# define JIT_FRET _V0
typedef jit_uint64_t jit_regset_t;
#elif defined(__s390__) || defined(__s390x__)
# define JIT_SP _R15
# define JIT_RET _R2
# define JIT_FRET _F0
typedef jit_uint32_t jit_regset_t;
#elif defined(__alpha__)
# define JIT_SP _SP
# define JIT_RET _V0
# define JIT_FRET _F0
typedef jit_uint64_t jit_regset_t;
#elif defined(__riscv)
# define JIT_RA0 _A0
# define JIT_FA0 _FA0
# define JIT_SP _SP
# define JIT_RET _A0
# define JIT_FRET _FA0
typedef jit_uint64_t jit_regset_t;
#endif
#define jit_data(u,v,w) _jit_data(_jit,u,v,w)
extern jit_node_t *_jit_data(jit_state_t*, const void*,
jit_word_t, jit_int32_t);
#define jit_size(vector) (sizeof(vector) / sizeof((vector)[0]))
#define jit_reg_free_p(regno) \
(!jit_regset_tstbit(&_jitc->reglive, regno) && \
!jit_regset_tstbit(&_jitc->regarg, regno) && \
!jit_regset_tstbit(&_jitc->regsav, regno))
#define jit_reg_free_if_spill_p(regno) \
(!jit_regset_tstbit(&_jitc->regarg, regno) && \
!jit_regset_tstbit(&_jitc->regsav, regno))
#define jit_inc_synth(code) \
do { \
(void)jit_new_node(jit_code_##code); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_w(code, u) \
do { \
(void)jit_new_node_w(jit_code_##code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_f(code, u) \
do { \
(void)jit_new_node_f(jit_code_##code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_d(code, u) \
do { \
(void)jit_new_node_d(jit_code_##code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_ww(code, u, v) \
do { \
(void)jit_new_node_ww(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_wp(code, u, v) \
do { \
(void)jit_new_node_wp(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_fp(code, u, v) \
do { \
(void)jit_new_node_fp(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_dp(code, u, v) \
do { \
(void)jit_new_node_dp(jit_code_##code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_dec_synth() jit_synth_dec()
#define jit_link_prolog() \
do { \
_jitc->tail->link = _jitc->function->prolog->link; \
_jitc->function->prolog->link = _jitc->tail; \
} while (0)
#define jit_link_prepare() \
do { \
_jitc->tail->link = _jitc->prepare->link; \
_jitc->prepare->link = _jitc->tail; \
} while (0)
#define jit_link_reverse(where) \
do { \
jit_node_t *tmp, *tail = 0; \
while (where) { \
tmp = (where)->link; \
(where)->link = tail; \
tail = where; \
where = tmp; \
} \
where = tail; \
} while (0);
/*
* Private jit_class bitmasks
*/
#define jit_class_named 0x00400000 /* hit must be the named reg */
#define jit_class_nospill 0x00800000 /* hint to fail if need spill */
#define jit_class_sft 0x01000000 /* not a hardware register */
#define jit_class_rg8 0x04000000 /* x86 8 bits */
#define jit_class_xpr 0x80000000 /* float / vector */
/* Used on sparc64 where %f0-%f31 can be encode for single float
* but %f32 to %f62 only as double precision */
#define jit_class_sng 0x10000000 /* Single precision float */
#define jit_class_dbl 0x20000000 /* Only double precision float */
#define jit_regno_patch 0x00008000 /* this is a register
* returned by a "user" call
* to jit_get_reg() */
#define jit_call_default 0
#define jit_call_varargs 1
#define jit_kind_register 1
#define jit_kind_code 2
#define jit_kind_word 3
#define jit_kind_float32 4
#define jit_kind_float64 5
#define jit_cc_a0_reg 0x00000001 /* arg0 is a register */
#define jit_cc_a0_chg 0x00000002 /* arg0 is modified */
#define jit_cc_a0_jmp 0x00000004 /* arg0 is a jump target */
#define jit_cc_a0_rlh 0x00000008 /* arg0 is a register pair */
#define jit_cc_a0_int 0x00000010 /* arg0 is immediate word */
#define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
#define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */
#define jit_cc_a0_arg 0x00000080 /* arg1 is an argument int id */
#define jit_cc_a1_reg 0x00000100 /* arg1 is a register */
#define jit_cc_a1_chg 0x00000200 /* arg1 is modified */
#define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */
#define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */
#define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */
#define jit_cc_a1_arg 0x00008000 /* arg1 is an argument node */
#define jit_cc_a2_reg 0x00010000 /* arg2 is a register */
#define jit_cc_a2_chg 0x00020000 /* arg2 is modified */
#define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
#define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
#define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
#if __ia64__ || (__sparc__ && __WORDSIZE == 64)
extern void
jit_regset_com(jit_regset_t*, jit_regset_t*);
extern void
jit_regset_and(jit_regset_t*, jit_regset_t*, jit_regset_t*);
extern void
jit_regset_ior(jit_regset_t*, jit_regset_t*, jit_regset_t*);
extern void
jit_regset_xor(jit_regset_t*, jit_regset_t*, jit_regset_t*);
extern void
jit_regset_set(jit_regset_t*, jit_regset_t*);
extern void
jit_regset_set_mask(jit_regset_t*, jit_int32_t);
extern jit_bool_t
jit_regset_cmp_ui(jit_regset_t*, jit_word_t);
extern void
jit_regset_set_ui(jit_regset_t*, jit_word_t);
extern jit_bool_t
jit_regset_set_p(jit_regset_t*);
extern void
jit_regset_clrbit(jit_regset_t*, jit_int32_t);
extern void
jit_regset_setbit(jit_regset_t*, jit_int32_t);
extern jit_bool_t
jit_regset_tstbit(jit_regset_t*, jit_int32_t);
# if __sparc__ && __WORDSIZE == 64
# define jit_regset_new(set) \
do { (set)->rl = (set)->rh = 0; } while (0)
# define jit_regset_del(set) \
do { (set)->rl = (set)->rh = 0; } while (0)
# else
# define jit_regset_new(set) \
do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
# define jit_regset_del(set) \
do { (set)->rl = (set)->rh = (set)->fl = (set)->fh = 0; } while (0)
# endif
#else
# define jit_regset_com(u, v) (*(u) = ~*(v))
# define jit_regset_and(u, v, w) (*(u) = *(v) & *(w))
# define jit_regset_ior(u, v, w) (*(u) = *(v) | *(w))
# define jit_regset_xor(u, v, w) (*(u) = *(v) ^ *(w))
# define jit_regset_set(u, v) (*(u) = *(v))
# define jit_regset_set_mask(u, v) (*(u) = (1LL << (v)) - 1)
# define jit_regset_cmp_ui(u, v) (*(u) != (v))
# define jit_regset_set_ui(u, v) (*(u) = (v))
# define jit_regset_set_p(set) (*set)
# define jit_regset_clrbit(set, bit) (*(set) &= ~(1LL << (bit)))
# define jit_regset_setbit(set, bit) (*(set) |= 1LL << (bit))
# define jit_regset_tstbit(set, bit) (*(set) & (1LL << (bit)))
# define jit_regset_new(set) (*(set) = 0)
# define jit_regset_del(set) (*(set) = 0)
#endif
extern unsigned long
jit_regset_scan1(jit_regset_t*, jit_int32_t);
#define jit_reglive_setup() \
do { \
jit_regset_set_ui(&_jitc->reglive, 0); \
jit_regset_set_ui(&_jitc->regmask, 0); \
} while (0)
/*
* Types
*/
typedef union jit_data jit_data_t;
typedef struct jit_note jit_note_t;
typedef struct jit_line jit_line_t;
typedef struct jit_block jit_block_t;
typedef struct jit_value jit_value_t;
typedef struct jit_compiler jit_compiler_t;
typedef struct jit_function jit_function_t;
typedef struct jit_register jit_register_t;
#if __arm__
# if DISASSEMBLER
typedef struct jit_data_info jit_data_info_t;
# endif
#endif
union jit_data {
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
jit_int32_t l;
jit_int32_t h;
#else
jit_int32_t h;
jit_int32_t l;
#endif
} q;
jit_word_t w;
jit_float32_t f;
jit_float64_t d;
jit_pointer_t p;
jit_node_t *n;
};
struct jit_note {
jit_uint8_t *code;
char *name;
jit_line_t *lines;
jit_word_t length;
jit_word_t size; /* of code */
};
struct jit_line {
char *file;
jit_int32_t *linenos;
jit_int32_t *offsets;
jit_word_t length;
};
struct jit_node {
jit_node_t *next;
jit_code_t code;
jit_uint16_t flag;
jit_uint16_t offset; /* Used if DEVEL_DISASSEMBLER */
jit_data_t u;
jit_data_t v;
jit_data_t w;
jit_node_t *link;
};
struct jit_block {
jit_node_t *label;
jit_regset_t reglive;
jit_regset_t regmask;
};
struct jit_value {
jit_int32_t kind;
jit_code_t code;
jit_data_t base;
jit_data_t disp;
};
typedef struct {
#if __arm__
jit_word_t kind;
#endif
jit_word_t inst;
jit_node_t *node;
} jit_patch_t;
#if __arm__ && DISASSEMBLER
struct jit_data_info {
jit_uword_t code; /* pointer in code buffer */
jit_word_t length; /* length of constant vector */
};
#endif
struct jit_function {
struct {
jit_int32_t argi;
jit_int32_t argf;
jit_int32_t size;
jit_int32_t aoff;
jit_int32_t alen;
jit_int32_t call;
jit_int32_t argn; /* for debug output */
} self;
struct {
jit_int32_t argi;
jit_int32_t argf;
jit_int32_t size;
jit_int32_t call;
} call;
jit_node_t *prolog;
jit_node_t *epilog;
jit_int32_t *regoff;
jit_regset_t regset;
jit_int32_t stack;
/* Helper for common jit generation pattern, used in GNU Smalltalk
* and possibly others, where a static frame layout is required or
* assumed. */
jit_int32_t frame;
jit_uint32_t define_frame : 1;
jit_uint32_t assume_frame : 1;
/* alloca offset offset */
jit_int32_t aoffoff;
/* uses allocar flag */
jit_uint32_t allocar : 1;
/* varargs state offsets */
jit_int32_t vaoff; /* offset of jit_va_list */
jit_int32_t vagp; /* first gp va argument */
jit_int32_t vafp; /* first fp va argument */
};
/* data used only during jit generation */
struct jit_compiler {
#if __ia64__
struct {
jit_uint64_t i : 41;
jit_uint64_t t : 4;
} inst[3];
jit_regset_t regs; /* changed regs since last stop */
jit_int32_t pred; /* changed preds last stop */
jit_int32_t ioff; /* offset in inst vector */
jit_int32_t rout; /* first output register */
jit_int32_t breg; /* base register for prolog/epilog */
#endif
#if __mips__ || __ia64__ || __alpha__ || \
(__sparc__ && __WORDSIZE == 64) || __riscv
jit_int32_t carry;
#define jit_carry _jitc->carry
#endif
jit_node_t *head;
jit_node_t *tail;
jit_node_t *prepare; /* inside prepare/finish* block */
jit_uint32_t realize : 1; /* jit_realize() called? */
jit_uint32_t dataset : 1; /* jit_dataset() called? */
jit_uint32_t done : 1; /* emit state finished */
jit_uint32_t emit : 1; /* emit state entered */
jit_uint32_t again : 1; /* start over emiting function */
jit_uint32_t synth : 8; /* emiting synthesized instructions */
#if DEBUG
jit_uint32_t getreg : 1;
#endif
jit_uint32_t no_data : 1;
jit_uint32_t no_note : 1;
jit_int32_t reglen; /* number of registers */
jit_regset_t regarg; /* cannot allocate */
jit_regset_t regsav; /* automatic spill only once */
jit_regset_t reglive; /* known live registers at some point */
jit_regset_t regmask; /* register mask to update reglive */
struct {
jit_uint8_t *end;
} code;
struct {
jit_uint8_t *ptr;
jit_node_t **table; /* very simple hash table */
jit_word_t size; /* number of vectors in table */
jit_word_t count; /* number of hash table entries */
jit_word_t offset; /* offset in bytes in ptr */
} data;
jit_node_t **spill;
jit_int32_t *gen; /* ssa like "register version" */
jit_value_t *values; /* temporary jit_value_t vector */
struct {
jit_block_t *ptr;
jit_word_t offset;
jit_word_t length;
} blocks; /* basic blocks */
struct {
jit_patch_t *ptr;
jit_word_t offset;
jit_word_t length;
} patches; /* forward patch information */
jit_function_t *function; /* current function */
struct {
jit_function_t *ptr;
jit_word_t offset;
jit_word_t length;
} functions; /* prolog/epilogue offsets in code */
struct {
jit_node_t **ptr;
jit_word_t offset;
jit_word_t length;
} pool;
jit_node_t *list;
struct {
jit_node_t *head; /* first note node */
jit_node_t *tail; /* linked list insertion */
/* fields to store temporary state information */
jit_word_t size;
jit_node_t *name;
jit_node_t *note;
jit_uint8_t *base;
} note;
#if __arm__
/* prevent using thumb instructions that set flags? */
jit_uint32_t no_set_flags : 1;
# if DISASSEMBLER
struct {
jit_data_info_t *ptr;
jit_word_t offset;
jit_word_t length;
} data_info; /* constant pools information */
# endif
/* Note that this field is somewhat hackish, but required by most
* ways to implement jit, unless implementing a pure one function
* per jit, as most times it needs to start the jit buffer with a
* jump where the "main" prolog starts, and because the initial
* code is in "arm mode", need to make an "arm mode" patch on that
* jump. A good example is the test suite assembler, where most
* test cases start with a "jmpi main" call. */
jit_uword_t thumb;
struct {
jit_uint8_t *data; /* pointer to code */
jit_word_t size; /* size data */
jit_word_t offset; /* pending patches */
jit_word_t length; /* number of pending constants */
jit_int32_t values[1024]; /* pending constants */
jit_word_t patches[2048];
} consts;
#elif (__powerpc__ && _CALL_AIXDESC) || __ia64__
/* Keep track of prolog addresses, just for the sake of making
* jit that starts with a jump to a "main" label work like other
* backends. */
struct {
jit_word_t *ptr;
jit_word_t offset;
jit_word_t length;
} prolog;
jit_bool_t jump;
#endif
#if GET_JIT_SIZE
/* Temporary storage to calculate instructions length */
jit_word_t size;
/* Global flag for code buffer heuristic size computation */
jit_word_t mult;
/* Pointer to code to prevent miscalculation if reallocating buffer */
jit_uint8_t *cptr;
#endif
};
#define _jitc _jit->comp
struct jit_state {
union {
jit_uint8_t *uc;
jit_uint16_t *us;
jit_uint32_t *ui;
jit_uint64_t *ul;
jit_word_t w;
} pc;
struct {
jit_uint8_t *ptr;
jit_word_t length;
} code;
struct {
jit_uint8_t *ptr;
jit_word_t length;
} data;
struct {
jit_note_t *ptr;
jit_word_t length;
} note;
jit_compiler_t *comp;
/* Flags to know if user did set the code and data buffers */
jit_uint32_t user_code : 1;
jit_uint32_t user_data : 1;
};
struct jit_register {
jit_reg_t spec;
char *name;
};
/*
* Prototypes
*/
extern void jit_get_cpu(void);
#define jit_init() _jit_init(_jit)
extern void _jit_init(jit_state_t*);
#define jit_synth_inc() _jit_synth_inc(_jit)
extern void _jit_synth_inc(jit_state_t*);
#define jit_new_node_no_link(u) _jit_new_node_no_link(_jit, u)
extern jit_node_t *_jit_new_node_no_link(jit_state_t*, jit_code_t);
#define jit_link_node(u) _jit_link_node(_jit, u)
extern void _jit_link_node(jit_state_t*, jit_node_t*);
#define jit_link_label(l) _jit_link_label(_jit,l)
extern void
_jit_link_label(jit_state_t*,jit_node_t*);
#define jit_synth_dec() _jit_synth_dec(_jit)
extern void _jit_synth_dec(jit_state_t*);
#define jit_reglive(node) _jit_reglive(_jit, node)
extern void
_jit_reglive(jit_state_t*, jit_node_t*);
#define jit_regarg_set(n,v) _jit_regarg_set(_jit,n,v)
extern void
_jit_regarg_set(jit_state_t*, jit_node_t*, jit_int32_t);
#define jit_regarg_clr(n,v) _jit_regarg_clr(_jit,n,v)
extern void
_jit_regarg_clr(jit_state_t*, jit_node_t*, jit_int32_t);
#define jit_get_reg(s) _jit_get_reg(_jit,s)
extern jit_int32_t
_jit_get_reg(jit_state_t*, jit_int32_t);
#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
extern void
_jit_unget_reg(jit_state_t*, jit_int32_t);
#define jit_save(reg) _jit_save(_jit, reg)
extern void
_jit_save(jit_state_t*, jit_int32_t);
#define jit_load(reg) _jit_load(_jit, reg)
extern void
_jit_load(jit_state_t*, jit_int32_t);
#define jit_trampoline(u,v) _jit_trampoline(_jit, u, v)
extern void _jit_trampoline(jit_state_t*, jit_int32_t, jit_bool_t);
#define jit_optimize() _jit_optimize(_jit)
extern void
_jit_optimize(jit_state_t*);
#define jit_classify(code) _jit_classify(_jit, code)
extern jit_int32_t
_jit_classify(jit_state_t*, jit_code_t);
#define jit_regarg_p(n, r) _jit_regarg_p(_jit, n, r)
extern jit_bool_t
_jit_regarg_p(jit_state_t*, jit_node_t*, jit_int32_t);
#define emit_code() _emit_code(_jit)
extern jit_pointer_t
_emit_code(jit_state_t*);
extern void
jit_flush(void *fptr, void *tptr);
#define emit_ldxi(r0, r1, i0) _emit_ldxi(_jit, r0, r1, i0)
extern void
_emit_ldxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
#define emit_stxi(i0, r0, r1) _emit_stxi(_jit, i0, r0, r1)
extern void
_emit_stxi(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
#define emit_ldxi_d(r0, r1, i0) _emit_ldxi_d(_jit, r0, r1, i0)
extern void
_emit_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
#define emit_stxi_d(i0, r0, r1) _emit_stxi_d(_jit, i0, r0, r1)
extern void
_emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
extern void jit_init_debug(const char*);
extern void jit_finish_debug(void);
extern void jit_init_note(void);
extern void jit_finish_note(void);
#define jit_set_note(n,u,v,w) _jit_set_note(_jit, n, u, v, w)
extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, jit_int32_t);
#define jit_annotate() _jit_annotate(_jit)
extern void _jit_annotate(jit_state_t*);
#define jit_print_node(u) _jit_print_node(_jit,u)
extern void _jit_print_node(jit_state_t*,jit_node_t*);
extern jit_pointer_t jit_memcpy(jit_pointer_t,const void*,jit_word_t);
extern jit_pointer_t jit_memmove(jit_pointer_t,const void*,jit_word_t);
extern void jit_alloc(jit_pointer_t*, jit_word_t);
extern void jit_realloc(jit_pointer_t*, jit_word_t, jit_word_t);
void jit_free(jit_pointer_t*);
extern void jit_init_size(void);
extern void jit_finish_size(void);
#if GET_JIT_SIZE
# define jit_size_prepare() _jit_size_prepare(_jit)
extern void
_jit_size_prepare(jit_state_t*);
# define jit_size_collect(node) _jit_size_collect(_jit, node)
extern void
_jit_size_collect(jit_state_t*, jit_node_t*);
#else
# define jit_get_size() _jit_get_size(_jit)
extern jit_word_t
_jit_get_size(jit_state_t*);
#endif
extern jit_word_t
jit_get_max_instr(void);
/*
* Externs
*/
extern jit_register_t _rvs[];
#endif /* _jit_private_h */
@@ -0,0 +1,147 @@
/*
* Copyright (C) 2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_riscv_h
#define _jit_riscv_h
#define JIT_HASH_CONSTS 0
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
#define JIT_FP _FP
typedef enum {
#define jit_r(i) (JIT_R0 + (i))
#define jit_r_num() 7
#define jit_v(i) (JIT_V0 + (i))
#define jit_v_num() 11
#define jit_f(i) (JIT_F0 + (i))
#define jit_f_num() 12
_ZERO, /* x0 - Hard-wired zero --- */
_RA, /* x1 - Return address (CalleR save) */
_SP, /* x2 - Stack pointer (CalleE save) */
_GP, /* x3 - Global pointer --- */
#if 0 /* Pretend it does not exist, so _NOREG can be used in
* a 64 bit bitmask */
_TP, /* x4 - Thread pointer --- */
#endif
#define JIT_R0 _T0
#define JIT_R1 _T1
#define JIT_R2 _T2
#define JIT_R3 _T3
#define JIT_R4 _T4
#define JIT_R5 _T5
#define JIT_R6 _T6
_T0, /* x5 - Temporary/alternate
link register (CalleR save) */
_T1, /* x6 - Temporary (CalleR save) */
_T2, /* x7 - Temporary (CalleR save) */
_T3, /* x28 - Temporary (CalleR save) */
_T4, /* x28 - Temporary (CalleR save) */
_T5, /* x30 - Temporary (CalleR save) */
_T6, /* x31 - Temporary (CalleR save) */
_FP, /* x8 - Saved register/frame
pointer (CalleE save) */
_S0 = _FP,
#define JIT_V0 _S1
#define JIT_V1 _S2
#define JIT_V2 _S3
#define JIT_V3 _S4
#define JIT_V4 _S5
#define JIT_V5 _S6
#define JIT_V6 _S7
#define JIT_V7 _S8
#define JIT_V8 _S9
#define JIT_V9 _S10
#define JIT_V10 _S11
_S1, /* x9 - Saved register (CalleE save) */
_S2, /* x18 - Saved register (CalleE save) */
_S3, /* x19 - Saved register (CalleE save) */
_S4, /* x20 - Saved register (CalleE save) */
_S5, /* x21 - Saved register (CalleE save) */
_S6, /* x22 - Saved register (CalleE save) */
_S7, /* x23 - Saved register (CalleE save) */
_S8, /* x24 - Saved register (CalleE save) */
_S9, /* x25 - Saved register (CalleE save) */
_S10, /* x26 - Saved register (CalleE save) */
_S11, /* x27 - Saved register (CalleE save) */
_A7, /* x17 - Function argument (CalleR save) */
_A6, /* x16 - Function argument (CalleR save) */
_A5, /* x15 - Function argument (CalleR save) */
_A4, /* x14 - Function argument (CalleR save) */
_A3, /* x13 - Function argument (CalleR save) */
_A2, /* x12 - Function argument (CalleR save) */
_A1, /* x11 - Function argument/
return value (CalleR save) */
_A0, /* x10 - Function argument/
return value (CalleR save) */
_FT0, /* f0 - FP temporary (CalleR save) */
_FT1, /* f1 - FP temporary (CalleR save) */
_FT2, /* f2 - FP temporary (CalleR save) */
_FT3, /* f3 - FP temporary (CalleR save) */
_FT4, /* f4 - FP temporary (CalleR save) */
_FT5, /* f5 - FP temporary (CalleR save) */
_FT6, /* f6 - FP temporary (CalleR save) */
_FT7, /* f7 - FP temporary (CalleR save) */
_FT8, /* f28 - FP temporary (CalleR save) */
_FT9, /* f29 - FP temporary (CalleR save) */
_FT10, /* f30 - FP temporary (CalleR save) */
_FT11, /* f31 - FP temporary (CalleR save) */
#define JIT_F0 _FS0
#define JIT_F1 _FS1
#define JIT_F2 _FS2
#define JIT_F3 _FS3
#define JIT_F4 _FS4
#define JIT_F5 _FS5
#define JIT_F6 _FS6
#define JIT_F7 _FS7
#define JIT_F8 _FS8
#define JIT_F9 _FS9
#define JIT_F10 _FS10
#define JIT_F11 _FS11
_FS0, /* f8 - FP saved register (CalleE save) */
_FS1, /* f9 - FP saved register (CalleE save) */
_FS2, /* f18 - FP saved register (CalleE save) */
_FS3, /* f19 - FP saved register (CalleE save) */
_FS4, /* f20 - FP saved register (CalleE save) */
_FS5, /* f21 - FP saved register (CalleE save) */
_FS6, /* f22 - FP saved register (CalleE save) */
_FS7, /* f23 - FP saved register (CalleE save) */
_FS8, /* f24 - FP saved register (CalleE save) */
_FS9, /* f25 - FP saved register (CalleE save) */
_FS10, /* f26 - FP saved register (CalleE save) */
_FS11, /* f27 - FP saved register (CalleE save) */
_FA7, /* f17 - FP Function argument (CalleR save) */
_FA6, /* f16 - FP Function argument (CalleR save) */
_FA5, /* f15 - FP Function argument (CalleR save) */
_FA4, /* f14 - FP Function argument (CalleR save) */
_FA3, /* f13 - FP Function argument (CalleR save) */
_FA2, /* f12 - FP Function argument (CalleR save) */
_FA1, /* f11 - FP function argument/
return value (CalleR save) */
_FA0, /* f10 - FP function argument/
return value (CalleR save) */
_NOREG,
#define JIT_NOREG _NOREG
} jit_reg_t;
#endif /* _jit_riscv_h */
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_s390_h
#define _jit_s390_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 2
/*
* Types
*/
#define JIT_FP _R13
typedef enum {
#define jit_r(i) (_R12 + ((i) << 1))
#define jit_r_num() 3
#define jit_v(i) (_R11 + ((i) << 1))
#define jit_v_num() 3
#define jit_f(i) (_F8 + (i))
#define jit_f_num() 6
#define JIT_R0 _R12
#define JIT_R1 _R10
#define JIT_R2 _R8
#define JIT_V0 _R11
#define JIT_V1 _R9
#define JIT_V2 _R7
_R0, _R1, /* Volatile */
_R12, /* Saved, GOT */
_R11, _R10, _R9, _R8, /* Saved */
_R7, /* Saved */
_R6, /* Saved, parameter */
_R5, _R4, _R3, /* Parameter passing */
_R2, /* Volatile, parameter and return value */
_R13, /* Saved, literal pool pointer */
_R14, /* Volatile, return address */
_R15, /* Saved, stack pointer */
#define JIT_F0 _F8
#define JIT_F1 _F9
#define JIT_F2 _F10
#define JIT_F3 _F11
#define JIT_F4 _F12
#define JIT_F5 _F13
_F1, _F3, _F5, _F7, /* Volatile */
_F14, _F15, _F8, _F9, /* Saved */
_F10, _F11, _F12, _F13, /* Saved */
_F6, _F4, _F2, /* Volatile, parameter */
_F0, /* Volatile, parameter and return value */
_NOREG,
#define JIT_NOREG _NOREG
} jit_reg_t;
#endif /* _jit_s390_h */
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_sparc_h
#define _jit_sparc_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
/*
* Types
*/
#define JIT_FP _FP
typedef enum {
#define jit_r(i) (_G2 + (i))
#define jit_r_num() 3
#define jit_v(i) (_L0 + (i))
#define jit_v_num() 8
#if __WORDSIZE == 32
# define jit_f(i) (_F0 + ((i) << 1))
# define jit_f_num() 8
#else
# define jit_f(i) (_F32 - (i))
# define jit_f_num() 16
#endif
#define JIT_R0 _G2
#define JIT_R1 _G3
#define JIT_R2 _G4
#define JIT_V0 _L0
#define JIT_V1 _L1
#define JIT_V2 _L2
#define JIT_V3 _L3
#define JIT_V4 _L4
#define JIT_V5 _L5
#define JIT_V6 _L6
#define JIT_V7 _L7
_G0, _G1, _G2, _G3, _G4, _G5, _G6, _G7,
_O0, _O1, _O2, _O3, _O4, _O5, _SP, _O7,
_L0, _L1, _L2, _L3, _L4, _L5, _L6, _L7,
_I0, _I1, _I2, _I3, _I4, _I5, _FP, _I7,
#if __WORDSIZE == 32
# define JIT_F0 _F0
# define JIT_F1 _F2
# define JIT_F2 _F4
# define JIT_F3 _F6
# define JIT_F4 _F8
# define JIT_F5 _F10
# define JIT_F6 _F12
# define JIT_F7 _F14
_F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7,
_F8, _F9, _F10, _F11, _F12, _F13, _F14, _F15,
#else
/* All single precision operations have a high cost due to being
* stored on registers only encodable as double precision.
* The cost is due to needing to move values to a register with
* value <= 31.
* This is a limitation due to using fixed named registers in
* lightning. */
# define JIT_F0 _F32
# define JIT_F1 _F34
# define JIT_F2 _F36
# define JIT_F3 _F38
# define JIT_F4 _F40
# define JIT_F5 _F42
# define JIT_F6 _F44
# define JIT_F7 _F46
# define JIT_F8 _F48
# define JIT_F9 _F50
# define JIT_F10 _F52
# define JIT_F11 _F54
# define JIT_F12 _F56
# define JIT_F13 _F58
# define JIT_F14 _F60
# define JIT_F15 _F62
_F62, _F60, _F58, _F56, _F54, _F52, _F50, _F48,
_F46, _F44, _F42, _F40, _F38, _F36, _F34, _F32,
_F31, _F30, _F29, _F28, _F27, _F26, _F25, _F24,
_F23, _F22, _F21, _F20, _F19, _F18, _F17, _F16,
_F15, _F14, _F13, _F12, _F11, _F10, _F9, _F8,
_F7, _F6, _F5, _F4, _F3, _F2, _F1, _F0,
#endif
#define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;
#endif /* _jit_sparc_h */
@@ -0,0 +1,199 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_x86_h
#define _jit_x86_h
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 2
/*
* Types
*/
#define jit_sse2_p() jit_cpu.sse2
#define jit_x87_reg_p(reg) ((reg) >= _ST0 && (reg) <= _ST6)
#if __WORDSIZE == 32
# if defined(__x86_64__)
# define __X64_32 1
# define __X64 1
# else
# define __X32 1
# endif
#else
# define __X64 1
#endif
#define JIT_FP _RBP
typedef enum {
#if __X32
# define jit_r(i) (_RAX + (i))
# define jit_r_num() 3
# define jit_v(i) (_RBX + (i))
# define jit_v_num() 3
# define jit_f(i) (jit_cpu.sse2 ? _XMM0 + (i) : _ST0 + (i))
# define jit_f_num() (jit_cpu.sse2 ? 8 : 6)
# define JIT_R0 _RAX
# define JIT_R1 _RCX
# define JIT_R2 _RDX
_RAX, _RCX, _RDX,
# define JIT_V0 _RBX
# define JIT_V1 _RSI
# define JIT_V2 _RDI
_RBX, _RSI, _RDI,
_RSP, _RBP,
# define JIT_F0 (jit_sse2_p() ? _XMM0 : _ST0)
# define JIT_F1 (jit_sse2_p() ? _XMM1 : _ST1)
# define JIT_F2 (jit_sse2_p() ? _XMM2 : _ST2)
# define JIT_F3 (jit_sse2_p() ? _XMM3 : _ST3)
# define JIT_F4 (jit_sse2_p() ? _XMM4 : _ST4)
# define JIT_F5 (jit_sse2_p() ? _XMM5 : _ST5)
# define JIT_F6 (jit_sse2_p() ? _XMM6 : _ST6)
_XMM0, _XMM1, _XMM2, _XMM3, _XMM4, _XMM5, _XMM6, _XMM7,
# define jit_sse_reg_p(reg) ((reg) >= _XMM0 && (reg) <= _XMM7)
#else
# if __CYGWIN__ || _WIN32
# define jit_r(i) (_RAX + (i))
# define jit_r_num() 3
# define jit_v(i) (_RBX + (i))
# define jit_v_num() 7
# define jit_f(index) (_XMM4 + (index))
# define jit_f_num() 12
# define JIT_R0 _RAX
# define JIT_R1 _R10
# define JIT_R2 _R11
# define JIT_V0 _RBX
# define JIT_V1 _RDI
# define JIT_V2 _RSI
# define JIT_V3 _R12
# define JIT_V4 _R13
# define JIT_V5 _R14
# define JIT_V6 _R15
/* Volatile - Return value register */
_RAX,
/* Volatile */
_R10, _R11,
/* Nonvolatile */
_RBX, _RDI, _RSI,
_R12, _R13, _R14, _R15,
/* Volatile - Integer arguments (4 to 1) */
_R9, _R8, _RDX, _RCX,
/* Nonvolatile */
_RSP, _RBP,
# define JIT_F0 _XMM4
# define JIT_F1 _XMM5
# define JIT_F2 _XMM6
# define JIT_F3 _XMM7
# define JIT_F4 _XMM8
# define JIT_F5 _XMM9
# define JIT_F6 _XMM10
# define JIT_F7 _XMM11
# define JIT_F8 _XMM12
# define JIT_F9 _XMM13
# define JIT_F10 _XMM14
# define JIT_F11 _XMM15
/* Volatile */
_XMM4, _XMM5,
/* Nonvolatile */
_XMM6, _XMM7, _XMM8, _XMM9, _XMM10,
_XMM11, _XMM12, _XMM13, _XMM14, _XMM15,
/* Volatile - FP arguments (4 to 1) */
_XMM3, _XMM2, _XMM1, _XMM0,
# define jit_sse_reg_p(reg) ((reg) >= _XMM4 && (reg) <= _XMM0)
# else
# define jit_r(i) (_RAX + (i))
# define jit_r_num() 3
# define jit_v(i) (_RBX + (i))
# define jit_v_num() 5
# define jit_f(index) (_XMM8 + (index))
# define jit_f_num() 8
# define JIT_R0 _RAX
# define JIT_R1 _R10
# define JIT_R2 _R11
_RAX, _R10, _R11,
# define JIT_V0 _RBX
# define JIT_V1 _R13
# define JIT_V2 _R14
# define JIT_V3 _R15
# define JIT_V4 _R12
_RBX, _R13, _R14, _R15, _R12,
_R9, _R8, _RCX, _RDX, _RSI, _RDI,
_RSP, _RBP,
# define JIT_F0 _XMM8
# define JIT_F1 _XMM9
# define JIT_F2 _XMM10
# define JIT_F3 _XMM11
# define JIT_F4 _XMM12
# define JIT_F5 _XMM13
# define JIT_F6 _XMM14
# define JIT_F7 _XMM15
_XMM8, _XMM9, _XMM10, _XMM11, _XMM12, _XMM13, _XMM14, _XMM15,
_XMM7, _XMM6, _XMM5, _XMM4, _XMM3, _XMM2, _XMM1, _XMM0,
# define jit_sse_reg_p(reg) ((reg) >= _XMM8 && (reg) <= _XMM0)
# endif
#endif
_ST0, _ST1, _ST2, _ST3, _ST4, _ST5, _ST6,
# define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;
typedef struct {
/* x87 present */
jit_uint32_t fpu : 1;
/* cmpxchg8b instruction */
jit_uint32_t cmpxchg8b : 1;
/* cmov and fcmov branchless conditional mov */
jit_uint32_t cmov : 1;
/* mmx registers/instructions available */
jit_uint32_t mmx : 1;
/* sse registers/instructions available */
jit_uint32_t sse : 1;
/* sse2 registers/instructions available */
jit_uint32_t sse2 : 1;
/* sse3 instructions available */
jit_uint32_t sse3 : 1;
/* pcmulqdq instruction */
jit_uint32_t pclmulqdq : 1;
/* ssse3 suplemental sse3 instructions available */
jit_uint32_t ssse3 : 1;
/* fused multiply/add using ymm state */
jit_uint32_t fma : 1;
/* cmpxchg16b instruction */
jit_uint32_t cmpxchg16b : 1;
/* sse4.1 instructions available */
jit_uint32_t sse4_1 : 1;
/* sse4.2 instructions available */
jit_uint32_t sse4_2 : 1;
/* movbe instruction available */
jit_uint32_t movbe : 1;
/* popcnt instruction available */
jit_uint32_t popcnt : 1;
/* aes instructions available */
jit_uint32_t aes : 1;
/* avx instructions available */
jit_uint32_t avx : 1;
/* lahf/sahf available in 64 bits mode */
jit_uint32_t lahf : 1;
} jit_cpu_t;
/*
* Initialization
*/
extern jit_cpu_t jit_cpu;
#endif /* _jit_x86_h */