Hi Paul,
sorry for download problems (I had some problems uploading to gnu.org -
should be fixed soon).
I you use a gcc version < 6 the problem comes form there (gcc >= 6 has
changed the PIC/PIE default output).
I have published some days ago a patch on the master branch which fixes
this problem.
You can download it from sourceforge git repo
(https://sourceforge.net/projects/gprolog/)
Or else you can simply replace src/Ma2Asm/x86_64_any.c by the attached
file, then
make clean
make
make check
should work
Daniel
On 11/1/18 4:01 AM, Paul Eggert wrote:
I recently tried to build gprolog 1.4.5 on RHEL 7.5 x86-64, and ran
into problems.
First, downloading is painful. With previous releases I could issue a
shell command like this:
wget https://ftp.gnu.org/gnu/gprolog/gprolog-1.4.4.tar.gz
But when I try that with 1.4.5, it doesn't work. Is there some reason
gprolog is no longer being distributed via gnu.org?
I then visited <https://gprolog.org/> and Firefox said, "Your
connection is not secure. The owner of gprolog.org has configured
their website improperly. To protect your information from being
stolen, Firefox has not connected to this website. gprolog.org uses an
invalid security certificate. The certificate is only valid for the
following names: *.univ-paris1.fr, trantor.univ-paris1.fr,
univ-paris1.fr Error code: SSL_ERROR_BAD_CERT_DOMAIN". Could you
please fix this? https: is becoming ssential nowadays.
So I backed off to <http://gprolog.org/>, and its Download section
points to <http://gprolog.org/gprolog-1.4.5.tar.gz>. This command does
work:
wget http://gprolog.org/gprolog-1.4.5.tar.gz
but it's http, not https, which is easily subject to man-in-the-middle
attacks.
After downloading I could not build gprolog. I ran these commands:
tar xf gprolog-1.4.5.tar.gz
cd gprolog-1.4.5/src
./configure --prefix=/usr/local/cs/gprolog-1.4.5
make
This eventually failed as follows:
...
gplc -c wam_emit.wam
[ ! -f pl2wam ] || cp pl2wam pl2wam0
gplc -o pl2wam --no-fd-lib-warn --no-top-level pl2wam.o read_file.o
syn_sugar.o internal.o code_gen.o reg_alloc.o inst_codif.o first_arg.o
indexing.o wam_emit.o
make[1]: Leaving directory `/dev/shm/eggert/gprolog-1.4.5/src/Pl2Wam'
make[1]: Entering directory `/dev/shm/eggert/gprolog-1.4.5/src/Fd2C'
gplc -c --fast-math fd2c.pl
Fatal Error: Segmentation Violation (bad address: 0x100ec814853)
compilation failed
make[1]: *** [fd2c.o] Error 1
make[1]: Leaving directory `/dev/shm/eggert/gprolog-1.4.5/src/Fd2C'
make: *** [all] Error 1
...
I went back to gprolog 1.4.4 and it downloaded and built without trouble.
My RHEL 7.5 platform has kernel 3.10.0-862.14.4.el7.x86_64 and gcc
(GCC) 4.8.5 20150623 (Red Hat 4.8.5-28). The CPU is an Intel Xeon
E5-2640 v2.
_______________________________________________
Bug-prolog mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-prolog
/*-------------------------------------------------------------------------*
* GNU Prolog *
* *
* Part : mini-assembler to assembler translator *
* File : x86_64_any.c *
* Descr.: translation file for Linux on AMD x86-64 *
* Author: Gwenole Beauchesne, Ozaki Kiichi and Daniel Diaz *
* *
* Copyright (C) 1999-2015 Daniel Diaz and Gwenole Beauchesne *
* *
* This file is part of GNU Prolog *
* *
* GNU Prolog is free software: you can redistribute it and/or *
* modify it under the terms of either: *
* *
* - the GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 3 of the License, or (at your *
* option) any later version. *
* *
* or *
* *
* - 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. *
* *
* or both in parallel, as here. *
* *
* GNU Prolog 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 copies of the GNU General Public License and *
* the GNU Lesser General Public License along with this program. If *
* not, see http://www.gnu.org/licenses/. *
*-------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* For M_x86_64_linux/solaris: an important point is that C stack must be
* aligned on 16 bytes else some problems occurs with double.
* If this is not done and if the called function performs a movaps %xmm0,xx
* an error will occur.
* Just before calling a function %rsp is 16bytes aligned, %rsp = 0x...0
* (4 low bits = 0). The callq instruction pushes the return address, so at
* the entry of a function, %rsp is 0x...8. Gcc then adjusts (via subq)
* %rsp to be 0x...0 before calling a function. We mimic the same modifying
* Call_Compiled to force %rsp to be 0x...0 when arriving in a Prolog code.
* So a Prolog code can call C functions safely.
* When a Prolog code finishes it returns into C inside Call_Prolog_Success
* or Call_Prolog_Fail. In both functions we re-adjust the stack (gcc thinks
* %rsp = 0x...8 while it is 0x...0): after the gcc adjustment code we
* force %rsp to be 0x...0.
* For MA c_code (MA code called by a C function), we have to reserve enough
* space in the stack to pass args to C functions. We receive %rsp = 0x...c
* In addition we have to push 1 register (%rbx)
* Thus 0x...8 - 8 = 0x...0 : OK ! We have to sub to %rsp the space for
* MAX_C_ARGS_IN_C_CODE*8 (this is OK if MAX_C_ARGS_IN_C_CODE is a multiple
* of 2). So we have to reserve: MAX_C_ARGS_IN_C_CODE * 8.
*
* Mac OS X Yosemite (14.0.0) using clang: similar problem when using an
* xmmN regs and movdqa instruction (for integ operations on longs = 64bits).
* It appeared in the chkma utility. Due to a global variable misaligned.
* defined initially with .comm _ma_array,40000,3
* problem was fixed using .comm _ma_array,40000,4
*/
/*---------------------------------*
* Constants *
*---------------------------------*/
#ifdef M_x86_64_darwin
#define STRING_PREFIX "L_.str"
#define DOUBLE_PREFIX "LCPI"
#define UN "_"
#define CONT_LABEL_FMT "Ltmp%d"
#else
#define STRING_PREFIX ".LC"
#define DOUBLE_PREFIX ".LCD"
#define UN
#define CONT_LABEL_FMT ".Lcont%d"
#endif
#define MAX_C_ARGS_IN_C_CODE 32 /* must be a multiple of 2 */
#define RESERVED_STACK_SPACE MAX_C_ARGS_IN_C_CODE * 8
#define MAX_DOUBLES_IN_PRED 2048
/*---------------------------------*
* Type Definitions *
*---------------------------------*/
/*---------------------------------*
* Global Variables *
*---------------------------------*/
static double dbl_tbl[MAX_DOUBLES_IN_PRED];
static int nb_dbl = 0;
static int dbl_lc_no = 0;
char asm_reg_e[20];
char asm_reg_b[20];
char asm_reg_cp[20];
int w_label = 0;
#ifdef _WIN32
#define MAX_PR_ARGS 4
static int pr_arg_no;
static const char *gpr_arg[MAX_PR_ARGS] = {
"%rcx", "%rdx", "%r8", "%r9"
};
static const char *fpr_arg[MAX_PR_ARGS] = {
"%xmm0", "%xmm1", "%xmm2", "%xmm3"
};
#else
#define MAX_GPR_ARGS 6
static int gpr_arg_no;
static const char *gpr_arg[MAX_GPR_ARGS] = {
"%rdi", "%rsi", "%rdx",
"%rcx", "%r8", "%r9"
};
#define MAX_FPR_ARGS 8
static int fpr_arg_no;
static const char *fpr_arg[MAX_FPR_ARGS] = {
"%xmm0", "%xmm1", "%xmm2", "%xmm3",
"%xmm4", "%xmm5", "%xmm6", "%xmm7"
};
#endif
/* variables for ma_parser.c / ma2asm.c */
int can_produce_pic_code = 1;
char *comment_prefix = "#";
#ifdef M_x86_64_darwin
char *local_symb_prefix = "L";
#else
char *local_symb_prefix = ".L";
#endif
int strings_need_null = 0;
int call_c_reverse_args = 0;
char *inline_asm_data[] = { NULL };
/*---------------------------------*
* Function Prototypes *
*---------------------------------*/
static char *Off_Reg_Bank(int offset);
#define LITTLE_INT(X) ((X) >= INT_MIN && (X) <= INT_MAX)
/*-------------------------------------------------------------------------*
* ASM_START *
* *
*-------------------------------------------------------------------------*/
void
Asm_Start(void)
{
/* M_x86_64_darwin needs a reg for pl_reg_bank (default is r12 see engine1.c)
* so NO_MACHINE_REG_FOR_REG_BANK is never set (see machine.h). Else this
* error occurs '32-bit absolute addressing is not supported for x86-64'
*/
#ifdef NO_MACHINE_REG_FOR_REG_BANK
#define ASM_REG_BANK "pl_reg_bank"
#elif defined(MAP_REG_BANK)
#define ASM_REG_BANK "%" MAP_REG_BANK
#else
#define ASM_REG_BANK "%r12"
#endif
#ifdef MAP_REG_E
sprintf(asm_reg_e, "%%%s", MAP_REG_E);
#else
strcpy(asm_reg_e, "%rbx");
#endif
#ifdef MAP_REG_B
sprintf(asm_reg_b, "%%%s", MAP_REG_B);
#else
strcpy(asm_reg_b, Off_Reg_Bank(MAP_OFFSET_B));
#endif
#ifdef MAP_REG_CP
sprintf(asm_reg_cp, "%%%s", MAP_REG_CP);
#else
strcpy(asm_reg_cp, Off_Reg_Bank(MAP_OFFSET_CP));
#endif
#if defined(M_x86_64_darwin) || defined(M_x86_64_bsd)
pic_code = 1; /* NB: on darwin and BSD everything is PIC code */
#elif defined(M_x86_64_linux) && __GNUC__ >= 6 /* gcc >= 6 needs PIC for linux */
pic_code = 1;
#elif defined(_WIN32)
pic_code = 0; /* NB: on MinGW nothing is needed for PIC code */
#endif
#ifdef M_x86_64_darwin
Inst_Printf(".section", "__TEXT,__text,regular,pure_instructions");
Inst_Printf(".align", "4, 0x90");
#else
Label_Printf(".text");
#endif
Label("fail");
Pl_Fail();
}
/*-------------------------------------------------------------------------*
* OFF_REG_BANK *
* *
*-------------------------------------------------------------------------*/
static char *
Off_Reg_Bank(int offset)
{
static char str[20];
#ifdef NO_MACHINE_REG_FOR_REG_BANK
sprintf(str, ASM_REG_BANK "+%d", offset);
#else
sprintf(str, "%d(%s)", offset, ASM_REG_BANK);
#endif
return str;
}
/*-------------------------------------------------------------------------*
* ASM_STOP *
* *
*-------------------------------------------------------------------------*/
void
Asm_Stop(void)
{
#ifdef __ELF__
Inst_Printf(".section", ".note.GNU-stack,\"\",@progbits");
#endif
}
/*-------------------------------------------------------------------------*
* CODE_START *
* *
*-------------------------------------------------------------------------*/
void
Code_Start(char *label, int prolog, int global)
{
int i;
int x = dbl_lc_no - nb_dbl;
for (i = 0; i < nb_dbl; i++)
{
union
{
double d;
unsigned int w[2];
} dbl;
dbl.d = dbl_tbl[i];
Label_Printf("%s%d:", DOUBLE_PREFIX, x++);
Inst_Printf(".long", "%d", dbl.w[0]);
Inst_Printf(".long", "%d", dbl.w[1]);
}
nb_dbl = 0;
Label_Printf("");
#ifdef M_x86_64_darwin
Inst_Printf(".align", "4, 0x90");
#else
#if 1 /* old code */
Inst_Printf(".p2align", "4,,15");
#else
Inst_Printf(".align", "16");
#endif
#if defined(M_x86_64_linux) || defined(M_x86_64_bsd) || defined(M_x86_64_sco)
Inst_Printf(".type", "%s,@function", label);
#endif
#endif
if (global)
Inst_Printf(".globl", UN "%s", label);
Label(label);
if (!prolog)
{
/* Save callee-saved registers. However, don't explicitly
preserve %r12-%r15 since they are already handled as global
-ffixed ones. */
Inst_Printf("pushq", "%%rbx");
Inst_Printf("subq", "$%d,%%rsp", RESERVED_STACK_SPACE);
}
}
/*-------------------------------------------------------------------------*
* CODE_STOP *
* *
*-------------------------------------------------------------------------*/
void
Code_Stop(void)
{
}
/*-------------------------------------------------------------------------*
* LABEL *
* *
*-------------------------------------------------------------------------*/
void
Label(char *label)
{
Label_Printf("");
Label_Printf(UN "%s:", label);
}
/*-------------------------------------------------------------------------*
* RELOAD_E_IN_REGISTER *
* *
*-------------------------------------------------------------------------*/
void
Reload_E_In_Register(void)
{
#ifndef MAP_REG_E
Inst_Printf("movq", "%s,%s", Off_Reg_Bank(MAP_OFFSET_E), asm_reg_e);
#endif
}
/*-------------------------------------------------------------------------*
* PL_JUMP *
* *
*-------------------------------------------------------------------------*/
void
Pl_Jump(char *label)
{
#ifndef M_x86_64_darwin
if (pic_code)
Inst_Printf("jmp", UN "%s@PLT", label);
else
#endif
Inst_Printf("jmp", UN "%s", label);
}
/*-------------------------------------------------------------------------*
* PREP_CP *
* *
*-------------------------------------------------------------------------*/
void
Prep_CP(void)
{
if (pic_code)
{
Inst_Printf("leaq", CONT_LABEL_FMT "(%%rip),%%r10", w_label);
Inst_Printf("movq", "%%r10,%s", asm_reg_cp);
}
else
{
Inst_Printf("movq", "$" CONT_LABEL_FMT ",%s", w_label, asm_reg_cp);
}
}
/*-------------------------------------------------------------------------*
* HERE_CP *
* *
*-------------------------------------------------------------------------*/
void
Here_CP(void)
{
Label_Printf(CONT_LABEL_FMT ":", w_label++);
}
/*-------------------------------------------------------------------------*
* PL_CALL *
* *
*-------------------------------------------------------------------------*/
void
Pl_Call(char *label)
{
Prep_CP();
Pl_Jump(label);
Here_CP();
}
/*-------------------------------------------------------------------------*
* PL_FAIL *
* *
*-------------------------------------------------------------------------*/
void
Pl_Fail(void)
{
#ifdef MAP_REG_B
Inst_Printf("jmp", "*-8(%s)", asm_reg_b);
#else
Inst_Printf("movq", "%s,%%rdx", asm_reg_b);
Inst_Printf("jmp", "*-8(%%rdx)");
#endif
}
/*-------------------------------------------------------------------------*
* PL_RET *
* *
*-------------------------------------------------------------------------*/
void
Pl_Ret(void)
{
#ifndef MAP_REG_CP
Inst_Printf("jmp", "*%s", asm_reg_cp);
#else
Inst_Printf("jmp", "%s", asm_reg_cp);
#endif
}
/*-------------------------------------------------------------------------*
* JUMP *
* *
*-------------------------------------------------------------------------*/
void
Jump(char *label)
{
#ifndef M_x86_64_darwin
if (pic_code)
Inst_Printf("jmp", UN "%s@PLT", label);
else
#endif
Inst_Printf("jmp", UN "%s", label);
}
/*-------------------------------------------------------------------------*
* MOVE_FROM_REG_X *
* *
*-------------------------------------------------------------------------*/
void
Move_From_Reg_X(int index)
{
Inst_Printf("movq", "%s,%%rdx", Off_Reg_Bank(index * 8));
}
/*-------------------------------------------------------------------------*
* MOVE_FROM_REG_Y *
* *
*-------------------------------------------------------------------------*/
void
Move_From_Reg_Y(int index)
{
Inst_Printf("movq", "%d(%s),%%rdx", Y_OFFSET(index), asm_reg_e);
}
/*-------------------------------------------------------------------------*
* MOVE_TO_REG_X *
* *
*-------------------------------------------------------------------------*/
void
Move_To_Reg_X(int index)
{
Inst_Printf("movq", "%%rdx,%s", Off_Reg_Bank(index * 8));
}
/*-------------------------------------------------------------------------*
* MOVE_TO_REG_Y *
* *
*-------------------------------------------------------------------------*/
void
Move_To_Reg_Y(int index)
{
Inst_Printf("movq", "%%rdx,%d(%s)", Y_OFFSET(index), asm_reg_e);
}
/*-------------------------------------------------------------------------*
* CALL_C_START *
* *
*-------------------------------------------------------------------------*/
void
Call_C_Start(char *fct_name, int fc, int nb_args, int nb_args_in_words,
char **p_inline)
{
#ifdef _WIN32
pr_arg_no = 0;
#else
gpr_arg_no = 0;
fpr_arg_no = 0;
#endif
}
#ifdef _WIN32
#define BEFORE_ARG \
{ \
char r[10], *r_aux; \
int r_eq_r_aux = 0; \
\
if (pr_arg_no < MAX_PR_ARGS) \
{ \
strcpy(r, gpr_arg[pr_arg_no++]); \
r_aux = r; \
r_eq_r_aux = 1; \
} \
else \
{ \
int nwords = offset; \
\
sprintf(r, "%d(%%rsp)", nwords * 8); \
r_aux = "%rax"; \
}
#define BEFORE_FPR_ARG \
{ \
char r[10], *r_aux; \
int r_eq_r_aux = 0; \
\
if (pr_arg_no < MAX_PR_ARGS) \
{ \
strcpy(r, fpr_arg[pr_arg_no++]); \
r_aux = r; \
r_eq_r_aux = 1; \
} \
else \
{ \
int nwords = offset; \
\
sprintf(r, "%d(%%rsp)", nwords * 8); \
r_aux = "%xmm8"; \
}
#else
#define BEFORE_ARG \
{ \
char r[10], *r_aux; \
int r_eq_r_aux = 0; \
\
if (gpr_arg_no < MAX_GPR_ARGS) \
{ \
strcpy(r, gpr_arg[gpr_arg_no++]); \
r_aux = r; \
r_eq_r_aux = 1; \
} \
else \
{ \
int nwords = offset - gpr_arg_no - fpr_arg_no; \
\
sprintf(r, "%d(%%rsp)", nwords * 8); \
r_aux = "%rax"; \
}
#define BEFORE_FPR_ARG \
{ \
char r[10], *r_aux; \
int r_eq_r_aux = 0; \
\
if (fpr_arg_no < MAX_FPR_ARGS) \
{ \
strcpy(r, fpr_arg[fpr_arg_no++]); \
r_aux = r; \
r_eq_r_aux = 1; \
} \
else \
{ \
int nwords = offset - gpr_arg_no - fpr_arg_no; \
\
sprintf(r, "%d(%%rsp)", nwords * 8); \
r_aux = "%xmm8"; \
}
#endif
#define AFTER_ARG \
}
#define AFTER_FPR_ARG \
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_INT *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Int(int offset, PlLong int_val)
{
BEFORE_ARG;
if (LITTLE_INT(int_val))
Inst_Printf("movq", "$%" PL_FMT_d ",%s", int_val, r);
else
{
Inst_Printf("movabsq", "$%" PL_FMT_d ",%s", int_val, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
}
AFTER_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_DOUBLE *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Double(int offset, double dbl_val)
{
BEFORE_FPR_ARG;
dbl_tbl[nb_dbl++] = dbl_val;
Inst_Printf("movsd", "%s%d(%%rip),%s", DOUBLE_PREFIX, dbl_lc_no++, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
AFTER_FPR_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_STRING *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_String(int offset, int str_no)
{
BEFORE_ARG;
if (pic_code)
{
Inst_Printf("leaq", "%s%d(%%rip),%s", STRING_PREFIX, str_no, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
}
else
{
Inst_Printf("movq", "$%s%d,%s", STRING_PREFIX, str_no, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
}
AFTER_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_MEM_L *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Mem_L(int offset, int adr_of, char *name, int index)
{
BEFORE_ARG;
if (pic_code)
{
Inst_Printf("movq", UN "%s@GOTPCREL(%%rip),%s", name, r_aux);
if (adr_of)
{
if (index != 0)
Inst_Printf("addq", "$%d,%s", index * 8, r_aux);
}
else
Inst_Printf("movq", "%d(%s),%s", index * 8, r_aux, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
}
else
{
if (adr_of)
Inst_Printf("movq", "$" "%s+%d,%s", name, index * 8, r);
else
{
Inst_Printf("movq", "%s+%d(%%rip),%s", name, index * 8, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
}
}
AFTER_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_REG_X *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Reg_X(int offset, int adr_of, int index)
{
BEFORE_ARG;
if (adr_of)
{
if (!r_eq_r_aux && index == 0)
{
#ifdef NO_MACHINE_REG_FOR_REG_BANK
Inst_Printf("movq", "$%s,%s", ASM_REG_BANK, r);
#else
Inst_Printf("movq", "%s,%s", ASM_REG_BANK, r);
#endif
goto finish;
}
Inst_Printf("leaq", "%s,%s", Off_Reg_Bank(index * 8), r_aux);
}
else
Inst_Printf("movq", "%s,%s", Off_Reg_Bank(index * 8), r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
finish:
; /* gcc3 does not like use of label at end of compound statement */
AFTER_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_REG_Y *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Reg_Y(int offset, int adr_of, int index)
{
BEFORE_ARG;
if (adr_of)
Inst_Printf("leaq", "%d(%s),%s", Y_OFFSET(index), asm_reg_e, r_aux);
else
Inst_Printf("movq", "%d(%s),%s", Y_OFFSET(index), asm_reg_e, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
AFTER_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_FOREIGN_L *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Foreign_L(int offset, int adr_of, int index)
{
BEFORE_ARG;
if (pic_code)
{
Inst_Printf("movq", UN "pl_foreign_long@GOTPCREL(%%rip), %s", r_aux);
if (adr_of)
{
if (index != 0)
Inst_Printf("addq", "$%d, %s", index * 8, r_aux);
}
else
Inst_Printf("movq", "%d(%s), %s", index * 8, r_aux, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s, %s", r_aux, r);
}
else
{
if (adr_of)
Inst_Printf("movq", "$" UN "pl_foreign_long+%d, %s", index * 8, r);
else
{
Inst_Printf("movq", UN "pl_foreign_long+%d(%%rip),%s", index * 8, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s, %s", r_aux, r);
}
}
AFTER_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_ARG_FOREIGN_D *
* *
*-------------------------------------------------------------------------*/
int
Call_C_Arg_Foreign_D(int offset, int adr_of, int index)
{
if (adr_of)
{
BEFORE_ARG;
if (pic_code)
{
Inst_Printf("movq", UN "pl_foreign_double@GOTPCREL(%%rip), %s", r_aux);
if (index != 0)
Inst_Printf("addq", "$%d, %s", index * 8, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s, %s", r_aux, r);
}
else
{
Inst_Printf("movq", "$" UN "pl_foreign_double+%d, %s", index * 8, r_aux);
if (!r_eq_r_aux)
Inst_Printf("movq", "%s,%s", r_aux, r);
}
AFTER_ARG;
return 1;
}
BEFORE_FPR_ARG;
if (pic_code)
{
Inst_Printf("movq", UN "pl_foreign_double@GOTPCREL(%%rip),%%r10");
Inst_Printf("movsd", "%d(%%r10), %s", index * 8, r_aux);
}
else
{
Inst_Printf("movsd", UN "pl_foreign_double+%d(%%rip),%s", index * 8, r_aux);
}
if (!r_eq_r_aux)
Inst_Printf("movsd", "%s, %s", r_aux, r);
AFTER_FPR_ARG;
return 1;
}
/*-------------------------------------------------------------------------*
* CALL_C_INVOKE *
* *
*-------------------------------------------------------------------------*/
void
Call_C_Invoke(char *fct_name, int fc, int nb_args, int nb_args_in_words)
{
#ifndef M_x86_64_darwin
if (pic_code)
Inst_Printf("call", UN "%s@PLT", fct_name);
else
#endif
Inst_Printf("call", UN "%s", fct_name);
}
/*-------------------------------------------------------------------------*
* CALL_C_STOP *
* *
*-------------------------------------------------------------------------*/
void
Call_C_Stop(char *fct_name, int nb_args, char **p_inline)
{
#ifndef MAP_REG_E
if (p_inline && INL_ACCESS_INFO(p_inline))
reload_e = 1;
#endif
}
/*-------------------------------------------------------------------------*
* JUMP_RET *
* *
*-------------------------------------------------------------------------*/
void
Jump_Ret(void)
{
Inst_Printf("jmp", "*%%rax");
}
/*-------------------------------------------------------------------------*
* FAIL_RET *
* *
*-------------------------------------------------------------------------*/
void
Fail_Ret(void)
{
Inst_Printf("test", "%%rax,%%rax");
Inst_Printf("je", UN "fail");
}
/*-------------------------------------------------------------------------*
* MOVE_RET_TO_MEM_L *
* *
*-------------------------------------------------------------------------*/
void
Move_Ret_To_Mem_L(char *name, int index)
{
if (pic_code)
{
Inst_Printf("movq", UN "%s@GOTPCREL(%%rip)," "%%r10", name);
Inst_Printf("movq", "%%rax," "%d(%%r10)", index * 8);
}
else
{
Inst_Printf("movq", "%%rax," "%s+%d(%%rip)", name, index * 8);
}
}
/*-------------------------------------------------------------------------*
* MOVE_RET_TO_REG_X *
* *
*-------------------------------------------------------------------------*/
void
Move_Ret_To_Reg_X(int index)
{ /* similar to Move_To_Reg_X */
Inst_Printf("movq", "%%rax,%s", Off_Reg_Bank(index * 8));
}
/*-------------------------------------------------------------------------*
* MOVE_RET_TO_REG_Y *
* *
*-------------------------------------------------------------------------*/
void
Move_Ret_To_Reg_Y(int index)
{ /* similar to Move_To_Reg_Y */
Inst_Printf("movq", "%%rax,%d(%s)", Y_OFFSET(index), asm_reg_e);
}
/*-------------------------------------------------------------------------*
* MOVE_RET_TO_FOREIGN_L *
* *
*-------------------------------------------------------------------------*/
void
Move_Ret_To_Foreign_L(int index)
{
if (pic_code)
{
Inst_Printf("movq", UN "pl_foreign_long@GOTPCREL(%%rip)," "%%r10");
Inst_Printf("movq", "%%rax," "%d(%%r10)", index * 8);
}
else
{
Inst_Printf("movq", "%%rax," UN "pl_foreign_long+%d(%%rip)", index * 8);
}
}
/*-------------------------------------------------------------------------*
* MOVE_RET_TO_FOREIGN_D *
* *
*-------------------------------------------------------------------------*/
void
Move_Ret_To_Foreign_D(int index)
{
if (pic_code)
{
Inst_Printf("movq", UN "pl_foreign_double@GOTPCREL(%%rip)," "%%r10");
Inst_Printf("movsd", "%%xmm0," "%d(%%r10)", index * 8);
}
else
{
Inst_Printf("movsd", "%%xmm0," UN "pl_foreign_double+%d(%%rip)", index * 8);
}
}
/*-------------------------------------------------------------------------*
* CMP_RET_AND_INT *
* *
*-------------------------------------------------------------------------*/
void
Cmp_Ret_And_Int(PlLong int_val)
{
if (int_val == 0)
Inst_Printf("testq", "%%rax,%%rax");
else if (LITTLE_INT(int_val))
Inst_Printf("cmpq", "$%" PL_FMT_d ",%%rax", int_val);
else
{
/* %rdx is second integral return value. At this stage, it is
bound to be dead since we only deal with primitive object
types. */
Inst_Printf("movabsq", "$%" PL_FMT_d ",%%rdx", int_val);
Inst_Printf("cmpq", "%%rdx,%%rax", int_val);
}
}
/*-------------------------------------------------------------------------*
* JUMP_IF_EQUAL *
* *
*-------------------------------------------------------------------------*/
void
Jump_If_Equal(char *label)
{
Inst_Printf("je", UN "%s", label);
}
/*-------------------------------------------------------------------------*
* JUMP_IF_GREATER *
* *
*-------------------------------------------------------------------------*/
void
Jump_If_Greater(char *label)
{
Inst_Printf("jg", UN "%s", label);
}
/*-------------------------------------------------------------------------*
* C_RET *
* *
*-------------------------------------------------------------------------*/
void
C_Ret(void)
{
Inst_Printf("addq", "$%d,%%rsp", RESERVED_STACK_SPACE);
Inst_Printf("popq", "%%rbx");
Inst_Printf("ret", "");
}
/*-------------------------------------------------------------------------*
* DICO_STRING_START *
* *
*-------------------------------------------------------------------------*/
void
Dico_String_Start(int nb_consts)
{
#ifdef M_x86_64_darwin
Inst_Printf(".section", UN "_TEXT,__cstring,cstring_literals");
#else
Label_Printf(".section\t.rodata");
#endif
}
/*-------------------------------------------------------------------------*
* DICO_STRING *
* *
*-------------------------------------------------------------------------*/
void
Dico_String(int str_no, char *asciiz)
{
Label_Printf("%s%d:", STRING_PREFIX, str_no);
#ifdef M_x86_64_darwin
Inst_Printf(".asciz", "%s", asciiz);
#else
Inst_Printf(".string", "%s", asciiz);
#endif
}
/*-------------------------------------------------------------------------*
* DICO_STRING_STOP *
* *
*-------------------------------------------------------------------------*/
void
Dico_String_Stop(int nb_consts)
{
}
/*-------------------------------------------------------------------------*
* DICO_LONG_START *
* *
*-------------------------------------------------------------------------*/
void
Dico_Long_Start(int nb_longs)
{
#ifdef M_x86_64_darwin
Inst_Printf(".section", "__DATA,__data");
Inst_Printf(".align", "3");
#else
Label_Printf(".data");
Inst_Printf(".align", "16");
#endif
}
/*-------------------------------------------------------------------------*
* DICO_LONG *
* *
*-------------------------------------------------------------------------*/
void
Dico_Long(char *name, int global, VType vtype, PlLong value)
{
PlLong size_bytes;
switch (vtype)
{
case NONE:
value = 1; /* then in case ARRAY_SIZE */
case ARRAY_SIZE:
size_bytes = value * 8;
#ifdef M_x86_64_darwin
if (!global)
Label_Printf(".zerofill __DATA,__bss," UN "%s,%" PL_FMT_d ",4", name, size_bytes);
else
Inst_Printf(".comm", UN "%s,%" PL_FMT_d ",4", name, size_bytes);
#else
#if defined(M_x86_64_linux) || defined(M_x86_64_sco) || \
defined(M_x86_64_solaris) || defined(M_x86_64_bsd)
if (!global)
Inst_Printf(".local", UN "%s", name);
#else
if (!global)
Inst_Printf(".lcomm", UN "%s,%" PL_FMT_d, name, size_bytes);
else
#endif
#if 1 /* work for all */
Inst_Printf(".comm", UN "%s,%" PL_FMT_d ",8", name, size_bytes);
#else /* this does not work under MinGW - not used for the moment */
if (value < 4)
Inst_Printf(".comm", UN "%s,%" PL_FMT_d ",8", name, size_bytes);
else
Inst_Printf(".comm", UN "%s,%" PL_FMT_d ",32", name, size_bytes);
#endif
#endif
break;
case INITIAL_VALUE:
if (global)
Inst_Printf(".globl", UN "%s", name);
#ifdef M_x86_64_darwin
Inst_Printf(".align", "3");
#else
Inst_Printf(".align", "8");
#endif
#if !(defined(M_x86_64_darwin) || defined(_WIN32))
Inst_Printf(".size", UN "%s,8", name);
#endif
Label_Printf(UN "%s:", name);
Inst_Printf(".quad", "%" PL_FMT_d, value);
break;
}
}
/*-------------------------------------------------------------------------*
* DICO_LONG_STOP *
* *
*-------------------------------------------------------------------------*/
void
Dico_Long_Stop(int nb_longs)
{
#ifdef M_x86_64_darwin
Label_Printf("\n\n.subsections_via_symbols");
#endif
}
/*-------------------------------------------------------------------------*
* DATA_START *
* *
*-------------------------------------------------------------------------*/
void
Data_Start(char *initializer_fct)
{
if (initializer_fct == NULL)
return;
#ifdef _MSC_VER
Inst_Printf(".section", ".GPLC$m");
#elif defined(__CYGWIN__) || defined(_WIN32)
Inst_Printf(".section", ".ctors,\"aw\"");
#elif defined(M_x86_64_darwin)
Inst_Printf(".section", "__DATA,__mod_init_func,mod_init_funcs");
#else
Inst_Printf(".section", ".ctors,\"aw\",@progbits");
#endif
#ifdef M_x86_64_darwin
Inst_Printf(".align", "3");
#else
Inst_Printf(".align", "8");
#endif
Inst_Printf(".quad", UN "%s", initializer_fct);
}
/*-------------------------------------------------------------------------*
* DATA_STOP *
* *
*-------------------------------------------------------------------------*/
void
Data_Stop(char *initializer_fct)
{
}
_______________________________________________
Bug-prolog mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-prolog