From 032352d98bcf65a05bd4f3f2f2d0e8b5fcd57c99 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sat, 10 Nov 2007 18:33:09 +0000 Subject: [PATCH] + darwin/x86_64 support git-svn-id: trunk@9180 - --- .gitattributes | 2 + compiler/aasmdata.pas | 2 +- compiler/cgobj.pas | 3 +- compiler/systems.pas | 2 +- compiler/systems/i_bsd.pas | 64 ++++ compiler/systems/t_bsd.pas | 5 + compiler/x86/agx86att.pas | 15 + compiler/x86/cgx86.pas | 12 +- compiler/x86_64/cgcpu.pas | 6 +- rtl/darwin/signal.inc | 4 + rtl/darwin/x86_64/sig_cpu.inc | 631 ++++++++++++++++++++++++++++++++++ rtl/darwin/x86_64/sighnd.inc | 56 +++ rtl/x86_64/math.inc | 29 +- rtl/x86_64/strings.inc | 5 +- 14 files changed, 824 insertions(+), 12 deletions(-) create mode 100644 rtl/darwin/x86_64/sig_cpu.inc create mode 100644 rtl/darwin/x86_64/sighnd.inc diff --git a/.gitattributes b/.gitattributes index dc5c8aef2e..cd1f434a59 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4527,6 +4527,8 @@ rtl/darwin/termiosproc.inc svneol=native#text/plain rtl/darwin/unxconst.inc svneol=native#text/plain rtl/darwin/unxfunc.inc svneol=native#text/plain rtl/darwin/unxsockh.inc svneol=native#text/plain +rtl/darwin/x86_64/sig_cpu.inc svneol=native#text/plain +rtl/darwin/x86_64/sighnd.inc svneol=native#text/plain rtl/embedded/Makefile svneol=native#text/plain rtl/embedded/Makefile.fpc svneol=native#text/plain rtl/embedded/check.inc svneol=native#text/plain diff --git a/compiler/aasmdata.pas b/compiler/aasmdata.pas index 2ba457b7a4..725a81013f 100644 --- a/compiler/aasmdata.pas +++ b/compiler/aasmdata.pas @@ -282,7 +282,7 @@ implementation for hal:=low(TAsmListType) to high(TAsmListType) do AsmLists[hal]:=TAsmList.create; { PIC data } - if (target_info.system in systems_darwin) then + if (target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin]) then AsmLists[al_picdata].concat(tai_directive.create(asd_non_lazy_symbol_pointer,'')); { CFI } FAsmCFI:=CAsmCFI.Create; diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index 4421435f25..c07b3e56ae 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -3781,8 +3781,7 @@ implementation case target_info.system of system_powerpc_darwin, system_i386_darwin, - system_powerpc64_darwin, - system_x86_64_darwin: + system_powerpc64_darwin: begin l:=current_asmdata.getasmsymbol('L'+symname+'$non_lazy_ptr'); if not(assigned(l)) then diff --git a/compiler/systems.pas b/compiler/systems.pas index 5ea9825cc1..168d97cfbe 100644 --- a/compiler/systems.pas +++ b/compiler/systems.pas @@ -837,7 +837,7 @@ begin {$endif} {$ifdef darwin} default_target(system_x86_64_darwin); - {$define source_system_set} + {$define default_target_set} {$endif} {$endif cpux86_64} { default is linux } diff --git a/compiler/systems/i_bsd.pas b/compiler/systems/i_bsd.pas index 0172255602..1d6377e253 100644 --- a/compiler/systems/i_bsd.pas +++ b/compiler/systems/i_bsd.pas @@ -577,6 +577,67 @@ unit i_bsd; + system_x86_64_darwin_info : tsysteminfo = + ( + system : system_x86_64_darwin; + name : 'Darwin for x86_64'; + shortname : 'Darwin'; + flags : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default]; + cpu : cpu_x86_64; + unit_env : 'BSDUNITS'; + extradefines : 'UNIX;BSD;HASUNIX'; + exeext : ''; + defext : '.def'; + scriptext : '.sh'; + smartext : '.sl'; + unitext : '.ppu'; + unitlibext : '.ppl'; + asmext : '.s'; + objext : '.o'; + resext : '.res'; + resobjext : '.or'; + sharedlibext : '.dylib'; + staticlibext : '.a'; + staticlibprefix : 'libp'; + sharedlibprefix : 'lib'; + sharedClibext : '.dylib'; + staticClibext : '.a'; + staticClibprefix : 'lib'; + sharedClibprefix : 'lib'; + Cprefix : '_'; + newline : #10; + dirsep : '/'; + assem : as_darwin; + assemextern : as_darwin; + link : nil; + linkextern : nil; + ar : ar_gnu_ar; + res : res_none; + dbg : dbg_dwarf2; + script : script_unix; + endian : endian_little; + alignment : + ( + procalign : 8; + loopalign : 4; + jumpalign : 0; + constalignmin : 0; + constalignmax : 8; + varalignmin : 0; + varalignmax : 16; + localalignmin : 4; + localalignmax : 8; + recordalignmin : 0; + recordalignmax : 8; + maxCrecordalign : 8 + ); + first_parm_offset : 16; + stacksize : 262144; + abi : abi_default; + ); + + + implementation initialization @@ -598,6 +659,9 @@ initialization {$ifdef FreeBSD} set_source_info(system_x86_64_FreeBSD_info); {$endif} + {$ifdef Darwin} + set_source_info(system_x86_64_darwin_info); + {$endif} {$endif} {$ifdef cpu68} {$ifdef NetBSD} diff --git a/compiler/systems/t_bsd.pas b/compiler/systems/t_bsd.pas index 32ee669113..3acbb3f3b3 100644 --- a/compiler/systems/t_bsd.pas +++ b/compiler/systems/t_bsd.pas @@ -693,6 +693,11 @@ initialization RegisterImport(system_x86_64_freebsd,timportlibbsd); RegisterExport(system_x86_64_freebsd,texportlibbsd); RegisterTarget(system_x86_64_freebsd_info); + + RegisterExternalLinker(system_x86_64_darwin_info,TLinkerBSD); + RegisterImport(system_x86_64_darwin,timportlibdarwin); + RegisterExport(system_x86_64_darwin,texportlibbsd); + RegisterTarget(system_x86_64_darwin_info); {$endif} {$ifdef i386} RegisterExternalLinker(system_i386_FreeBSD_info,TLinkerBSD); diff --git a/compiler/x86/agx86att.pas b/compiler/x86/agx86att.pas index d6c9a1cc98..bf81a55d61 100644 --- a/compiler/x86/agx86att.pas +++ b/compiler/x86/agx86att.pas @@ -296,6 +296,20 @@ interface labelprefix : '.L'; comment : '# '; ); + + + as_x86_64_gas_darwin_info : tasminfo = + ( + id : as_darwin; + idtxt : 'AS-Darwin'; + asmbin : 'as'; + asmcmd : '-o $OBJ $ASM -arch x86_64'; + supported_target : system_any; + flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf]; + labelprefix : 'L'; + comment : '# '; + ); + {$else x86_64} as_i386_as_info : tasminfo = ( @@ -351,6 +365,7 @@ interface initialization {$ifdef x86_64} RegisterAssembler(as_x86_64_as_info,Tx86ATTAssembler); + RegisterAssembler(as_x86_64_gas_darwin_info,Tx86AppleGNUAssembler); {$else x86_64} RegisterAssembler(as_i386_as_info,Tx86ATTAssembler); RegisterAssembler(as_i386_gas_info,Tx86ATTAssembler); diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 86fcbd11f8..8203cd82a2 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -623,7 +623,9 @@ unit cgx86; begin sym:=current_asmdata.RefAsmSymbol(s); reference_reset_symbol(r,sym,0); - if cs_create_pic in current_settings.moduleswitches then + if (cs_create_pic in current_settings.moduleswitches) and + { darwin/x86_64's assembler doesn't want @PLT after call symbols } + (target_info.system<>system_x86_64_darwin) then begin {$ifdef i386} include(current_procinfo.flags,pi_needs_got); @@ -2021,13 +2023,13 @@ unit cgx86; { allocate stackframe space } if (localsize<>0) or - ((target_info.system in [system_i386_darwin, + ((target_info.system in [system_i386_darwin,system_x86_64_darwin, system_x86_64_win64,system_x86_64_linux,system_x86_64_freebsd]) and (stackmisalignment <> 0) and ((pi_do_call in current_procinfo.flags) or (po_assembler in current_procinfo.procdef.procoptions))) then begin - if (target_info.system in [system_i386_darwin, + if (target_info.system in [system_i386_darwin,system_x86_64_darwin, system_x86_64_win64,system_x86_64_linux,system_x86_64_freebsd]) then localsize := align(localsize+stackmisalignment,16)-stackmisalignment; cg.g_stackpointer_alloc(list,localsize); @@ -2080,7 +2082,9 @@ unit cgx86; reference_reset_symbol(ref,sym,0); { create pic'ed? } - if cs_create_pic in current_settings.moduleswitches then + if (cs_create_pic in current_settings.moduleswitches) and + { darwin/x86_64's assembler doesn't want @PLT after call symbols } + (target_info.system<>system_x86_64_darwin) then begin { it could be that we're called from a procedure not having the got loaded diff --git a/compiler/x86_64/cgcpu.pas b/compiler/x86_64/cgcpu.pas index e28620fca8..56c885a91a 100644 --- a/compiler/x86_64/cgcpu.pas +++ b/compiler/x86_64/cgcpu.pas @@ -137,7 +137,7 @@ unit cgcpu; if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then begin stacksize:=current_procinfo.calc_stackframe_size; - if (target_info.system in [system_x86_64_win64,system_x86_64_linux,system_x86_64_freebsd]) and + if (target_info.system in [system_x86_64_win64,system_x86_64_linux,system_x86_64_freebsd,system_x86_64_darwin]) and ((stacksize <> 0) or (pi_do_call in current_procinfo.flags) or { can't detect if a call in this case -> use nostackframe } @@ -205,7 +205,9 @@ unit cgcpu; begin sym:=current_asmdata.RefAsmSymbol(procdef.mangledname); reference_reset_symbol(r,sym,0); - if cs_create_pic in current_settings.moduleswitches then + if (cs_create_pic in current_settings.moduleswitches) and + { darwin/x86_64's assembler doesn't want @PLT after call symbols } + (target_info.system<>system_x86_64_darwin) then r.refaddr:=addr_pic else r.refaddr:=addr_full; diff --git a/rtl/darwin/signal.inc b/rtl/darwin/signal.inc index 02cb873107..ab46f19c9b 100644 --- a/rtl/darwin/signal.inc +++ b/rtl/darwin/signal.inc @@ -181,7 +181,11 @@ {$ifdef cpui386} {$include i386/sig_cpu.inc} { SigContextRec } {$else cpui386} +{$ifdef cpux86_64} + {$include x86_64/sig_cpu.inc} { SigContextRec } +{$else cpux86_64} {$error Unsupported cpu type!} +{$endif cpux86_64} {$endif cpui386} {$endif cpupowerpc or cpupowerpc64} diff --git a/rtl/darwin/x86_64/sig_cpu.inc b/rtl/darwin/x86_64/sig_cpu.inc new file mode 100644 index 0000000000..e96559e20c --- /dev/null +++ b/rtl/darwin/x86_64/sig_cpu.inc @@ -0,0 +1,631 @@ + +{$IFDEF FPC} +{$PACKRECORDS C} +{$ENDIF} + + + { + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + } + { + * @OSF_COPYRIGHT@ + } + { + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + } + { + } + { + * File: thread_status.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * This file contains the structure definitions for the thread + * state as applied to I386 processors. + } + { + * i386_thread_state this is the structure that is exported + * to user threads for use in status/mutate + * calls. This structure should never + * change. + * + * i386_float_state exported to use threads for access to + * floating point registers. Try not to + * change this one, either. + * + } + { THREAD_STATE_FLAVOR_LIST 0 } + +{ + const + i386_THREAD_STATE = 1; + i386_FLOAT_STATE = 2; + i386_EXCEPTION_STATE = 3; + THREAD_STATE_NONE = 4; +} + { + * Main thread state consists of + * general registers, segment registers, + * eip and eflags. + } + + type + x86_64_thread_state = record + rax : cuint64; + rbx : cuint64; + rcx : cuint64; + rdx : cuint64; + rdi : cuint64; + rsi : cuint64; + rbp : cuint64; + rsp : cuint64; + r8 : cuint64; + r9 : cuint64; + r10 : cuint64; + r11 : cuint64; + r12 : cuint64; + r13 : cuint64; + r14 : cuint64; + r15 : cuint64; + rip : cuint64; + rflags : cuint64; + cs : cuint64; + fs : cuint64; + gs : cuint64; + end; + x86_64_thread_state_t = x86_64_thread_state; + { + * Default segment register values. + } + + const + USER_CODE_SELECTOR = $0017; + USER_DATA_SELECTOR = $001f; + KERN_CODE_SELECTOR = $0008; + KERN_DATA_SELECTOR = $0010; + FP_PREC_24B = 0; + FP_PREC_53B = 2; + FP_PREC_64B = 3; + FP_RND_NEAR = 0; + FP_RND_DOWN = 1; + FP_RND_UP = 2; + FP_CHOP = 3; + + type + + fp_control = record + flag0 : cushort; + end; + fp_control_t = fp_control; + + const + bm_fp_control_invalid = $1; + bp_fp_control_invalid = 0; + bm_fp_control_denorm = $2; + bp_fp_control_denorm = 1; + bm_fp_control_zdiv = $4; + bp_fp_control_zdiv = 2; + bm_fp_control_ovrfl = $8; + bp_fp_control_ovrfl = 3; + bm_fp_control_undfl = $10; + bp_fp_control_undfl = 4; + bm_fp_control_precis = $20; + bp_fp_control_precis = 5; + bm_fp_control_x = $C0; + bp_fp_control_x = 6; + bm_fp_control_pc = $300; + bp_fp_control_pc = 8; + bm_fp_control_rc = $C00; + bp_fp_control_rc = 10; + bm_fp_control_inf = $1000; + bp_fp_control_inf = 12; + bm_fp_control_y = $E000; + bp_fp_control_y = 13; + +(* + function invalid(var a : fp_control) : word; + procedure set_invalid(var a : fp_control; __invalid : word); + function denorm(var a : fp_control) : word; + procedure set_denorm(var a : fp_control; __denorm : word); + function zdiv(var a : fp_control) : word; + procedure set_zdiv(var a : fp_control; __zdiv : word); + function ovrfl(var a : fp_control) : word; + procedure set_ovrfl(var a : fp_control; __ovrfl : word); + function undfl(var a : fp_control) : word; + procedure set_undfl(var a : fp_control; __undfl : word); + function precis(var a : fp_control) : word; + procedure set_precis(var a : fp_control; __precis : word); + function pc(var a : fp_control) : word; + procedure set_pc(var a : fp_control; __pc : word); + function rc(var a : fp_control) : word; + procedure set_rc(var a : fp_control; __rc : word); + function inf(var a : fp_control) : word; + procedure set_inf(var a : fp_control; __inf : word); +*) + { + * Status word. + } + + type + + fp_status = record + flag0 : cushort; + end; + fp_status_t = fp_status; + + const + bm_fp_status_invalid = $1; + bp_fp_status_invalid = 0; + bm_fp_status_denorm = $2; + bp_fp_status_denorm = 1; + bm_fp_status_zdiv = $4; + bp_fp_status_zdiv = 2; + bm_fp_status_ovrfl = $8; + bp_fp_status_ovrfl = 3; + bm_fp_status_undfl = $10; + bp_fp_status_undfl = 4; + bm_fp_status_precis = $20; + bp_fp_status_precis = 5; + bm_fp_status_stkflt = $40; + bp_fp_status_stkflt = 6; + bm_fp_status_errsumm = $80; + bp_fp_status_errsumm = 7; + bm_fp_status_c0 = $100; + bp_fp_status_c0 = 8; + bm_fp_status_c1 = $200; + bp_fp_status_c1 = 9; + bm_fp_status_c2 = $400; + bp_fp_status_c2 = 10; + bm_fp_status_tos = $3800; + bp_fp_status_tos = 11; + bm_fp_status_c3 = $4000; + bp_fp_status_c3 = 14; + bm_fp_status_busy = $8000; + bp_fp_status_busy = 15; + +{ + function invalid(var a : fp_status) : word; + procedure set_invalid(var a : fp_status; __invalid : word); + function denorm(var a : fp_status) : word; + procedure set_denorm(var a : fp_status; __denorm : word); + function zdiv(var a : fp_status) : word; + procedure set_zdiv(var a : fp_status; __zdiv : word); + function ovrfl(var a : fp_status) : word; + procedure set_ovrfl(var a : fp_status; __ovrfl : word); + function undfl(var a : fp_status) : word; + procedure set_undfl(var a : fp_status; __undfl : word); + function precis(var a : fp_status) : word; + procedure set_precis(var a : fp_status; __precis : word); + function stkflt(var a : fp_status) : word; + procedure set_stkflt(var a : fp_status; __stkflt : word); + function errsumm(var a : fp_status) : word; + procedure set_errsumm(var a : fp_status; __errsumm : word); + function c0(var a : fp_status) : word; + procedure set_c0(var a : fp_status; __c0 : word); + function c1(var a : fp_status) : word; + procedure set_c1(var a : fp_status; __c1 : word); + function c2(var a : fp_status) : word; + procedure set_c2(var a : fp_status; __c2 : word); + function tos(var a : fp_status) : word; + procedure set_tos(var a : fp_status; __tos : word); + function c3(var a : fp_status) : word; + procedure set_c3(var a : fp_status; __c3 : word); + function busy(var a : fp_status) : word; + procedure set_busy(var a : fp_status; __busy : word); +} + + { defn of 80bit x87 FPU or MMX register } + + type + mmst_reg = record + mmst_reg : array[0..9] of byte; + mmst_rsrv : array[0..5] of byte; + end; + + { defn of 128 bit XMM regs } + xmm_reg = record + xmm_reg : array[0..15] of byte; + end; + + { + * Floating point state. + } + { number of chars worth of data from fpu_fcw } + + const + FP_STATE_BYTES = 512; + { For legacy reasons we need to leave the hw_state as char bytes } + { x87 FPU control word } + { x87 FPU status word } + { x87 FPU tag word } + { reserved } { x87 FPU Opcode } + { x87 FPU Instruction Pointer offset } + { x87 FPU Instruction Pointer Selector } + { reserved } + { x87 FPU Instruction Operand(Data) Pointer offset } + { x87 FPU Instruction Operand(Data) Pointer Selector } + { reserved } + { MXCSR Register state } + { MXCSR mask } + { ST0/MM0 } + { ST1/MM1 } + { ST2/MM2 } + { ST3/MM3 } + { ST4/MM4 } + { ST5/MM5 } + { ST6/MM6 } + { ST7/MM7 } + { XMM 0 } + { XMM 1 } + { XMM 2 } + { XMM 3 } + { XMM 4 } + { XMM 5 } + { XMM 6 } + { XMM 7 } + { reserved } + + type + x86_64_float_state = record + fpu_reserved : array[0..1] of cint; + fpu_fcw : fp_control_t; + fpu_fsw : fp_status_t; + fpu_ftw : cuint8; + fpu_rsrv1 : cuint8; + fpu_fop : cuint16; + fpu_ip : cuint32; + fpu_cs : cuint16; + fpu_rsrv2 : cuint16; + fpu_dp : cuint32; + fpu_ds : cuint16; + fpu_rsrv3 : cuint16; + fpu_mxcsr : cuint32; + fpu_mxcsrmask : cuint32; + fpu_stmm0 : mmst_reg; + fpu_stmm1 : mmst_reg; + fpu_stmm2 : mmst_reg; + fpu_stmm3 : mmst_reg; + fpu_stmm4 : mmst_reg; + fpu_stmm5 : mmst_reg; + fpu_stmm6 : mmst_reg; + fpu_stmm7 : mmst_reg; + fpu_xmm0 : xmm_reg; + fpu_xmm1 : xmm_reg; + fpu_xmm2 : xmm_reg; + fpu_xmm3 : xmm_reg; + fpu_xmm4 : xmm_reg; + fpu_xmm5 : xmm_reg; + fpu_xmm6 : xmm_reg; + fpu_xmm7 : xmm_reg; + fpu_xmm8 : xmm_reg; + fpu_xmm9 : xmm_reg; + fpu_xmm10 : xmm_reg; + fpu_xmm11 : xmm_reg; + fpu_xmm12 : xmm_reg; + fpu_xmm13 : xmm_reg; + fpu_xmm14 : xmm_reg; + fpu_xmm15 : xmm_reg; + fpu_rsrv4 : array[0..(6*16)-1] of byte; + fpu_reserved1 : cint; + end; + + x86_64_float_state_t = x86_64_float_state; + { + * Extra state that may be + * useful to exception handlers. + } + x86_64_exception_state = record + trapno : cuint; + err : cuint; + faultvaddr : cuint64; + end; + + x86_64_exception_state_t = x86_64_exception_state; + + +(* + function invalid(var a : fp_control) : word; + begin + invalid:=(a.flag0 and bm_fp_control_invalid) shr bp_fp_control_invalid; + end; + + procedure set_invalid(var a : fp_control; __invalid : word); + begin + a.flag0:=a.flag0 or ((__invalid shl bp_fp_control_invalid) and bm_fp_control_invalid); + end; + + function denorm(var a : fp_control) : word; + begin + denorm:=(a.flag0 and bm_fp_control_denorm) shr bp_fp_control_denorm; + end; + + procedure set_denorm(var a : fp_control; __denorm : word); + begin + a.flag0:=a.flag0 or ((__denorm shl bp_fp_control_denorm) and bm_fp_control_denorm); + end; + + function zdiv(var a : fp_control) : word; + begin + zdiv:=(a.flag0 and bm_fp_control_zdiv) shr bp_fp_control_zdiv; + end; + + procedure set_zdiv(var a : fp_control; __zdiv : word); + begin + a.flag0:=a.flag0 or ((__zdiv shl bp_fp_control_zdiv) and bm_fp_control_zdiv); + end; + + function ovrfl(var a : fp_control) : word; + begin + ovrfl:=(a.flag0 and bm_fp_control_ovrfl) shr bp_fp_control_ovrfl; + end; + + procedure set_ovrfl(var a : fp_control; __ovrfl : word); + begin + a.flag0:=a.flag0 or ((__ovrfl shl bp_fp_control_ovrfl) and bm_fp_control_ovrfl); + end; + + function undfl(var a : fp_control) : word; + begin + undfl:=(a.flag0 and bm_fp_control_undfl) shr bp_fp_control_undfl; + end; + + procedure set_undfl(var a : fp_control; __undfl : word); + begin + a.flag0:=a.flag0 or ((__undfl shl bp_fp_control_undfl) and bm_fp_control_undfl); + end; + + function precis(var a : fp_control) : word; + begin + precis:=(a.flag0 and bm_fp_control_precis) shr bp_fp_control_precis; + end; + + procedure set_precis(var a : fp_control; __precis : word); + begin + a.flag0:=a.flag0 or ((__precis shl bp_fp_control_precis) and bm_fp_control_precis); + end; + + function x(var a : fp_control) : word; + begin + x:=(a.flag0 and bm_fp_control_x) shr bp_fp_control_x; + end; + + procedure set_x(var a : fp_control; __x : word); + begin + a.flag0:=a.flag0 or ((__x shl bp_fp_control_x) and bm_fp_control_x); + end; + + function pc(var a : fp_control) : word; + begin + pc:=(a.flag0 and bm_fp_control_pc) shr bp_fp_control_pc; + end; + + procedure set_pc(var a : fp_control; __pc : word); + begin + a.flag0:=a.flag0 or ((__pc shl bp_fp_control_pc) and bm_fp_control_pc); + end; + + function rc(var a : fp_control) : word; + begin + rc:=(a.flag0 and bm_fp_control_rc) shr bp_fp_control_rc; + end; + + procedure set_rc(var a : fp_control; __rc : word); + begin + a.flag0:=a.flag0 or ((__rc shl bp_fp_control_rc) and bm_fp_control_rc); + end; + + function inf(var a : fp_control) : word; + begin + inf:=(a.flag0 and bm_fp_control_inf) shr bp_fp_control_inf; + end; + + procedure set_inf(var a : fp_control; __inf : word); + begin + a.flag0:=a.flag0 or ((__inf shl bp_fp_control_inf) and bm_fp_control_inf); + end; + + function y(var a : fp_control) : word; + begin + y:=(a.flag0 and bm_fp_control_y) shr bp_fp_control_y; + end; + + procedure set_y(var a : fp_control; __y : word); + begin + a.flag0:=a.flag0 or ((__y shl bp_fp_control_y) and bm_fp_control_y); + end; + + function invalid(var a : fp_status) : word; + begin + invalid:=(a.flag0 and bm_fp_status_invalid) shr bp_fp_status_invalid; + end; + + procedure set_invalid(var a : fp_status; __invalid : word); + begin + a.flag0:=a.flag0 or ((__invalid shl bp_fp_status_invalid) and bm_fp_status_invalid); + end; + + function denorm(var a : fp_status) : word; + begin + denorm:=(a.flag0 and bm_fp_status_denorm) shr bp_fp_status_denorm; + end; + + procedure set_denorm(var a : fp_status; __denorm : word); + begin + a.flag0:=a.flag0 or ((__denorm shl bp_fp_status_denorm) and bm_fp_status_denorm); + end; + + function zdiv(var a : fp_status) : word; + begin + zdiv:=(a.flag0 and bm_fp_status_zdiv) shr bp_fp_status_zdiv; + end; + + procedure set_zdiv(var a : fp_status; __zdiv : word); + begin + a.flag0:=a.flag0 or ((__zdiv shl bp_fp_status_zdiv) and bm_fp_status_zdiv); + end; + + function ovrfl(var a : fp_status) : word; + begin + ovrfl:=(a.flag0 and bm_fp_status_ovrfl) shr bp_fp_status_ovrfl; + end; + + procedure set_ovrfl(var a : fp_status; __ovrfl : word); + begin + a.flag0:=a.flag0 or ((__ovrfl shl bp_fp_status_ovrfl) and bm_fp_status_ovrfl); + end; + + function undfl(var a : fp_status) : word; + begin + undfl:=(a.flag0 and bm_fp_status_undfl) shr bp_fp_status_undfl; + end; + + procedure set_undfl(var a : fp_status; __undfl : word); + begin + a.flag0:=a.flag0 or ((__undfl shl bp_fp_status_undfl) and bm_fp_status_undfl); + end; + + function precis(var a : fp_status) : word; + begin + precis:=(a.flag0 and bm_fp_status_precis) shr bp_fp_status_precis; + end; + + procedure set_precis(var a : fp_status; __precis : word); + begin + a.flag0:=a.flag0 or ((__precis shl bp_fp_status_precis) and bm_fp_status_precis); + end; + + function stkflt(var a : fp_status) : word; + begin + stkflt:=(a.flag0 and bm_fp_status_stkflt) shr bp_fp_status_stkflt; + end; + + procedure set_stkflt(var a : fp_status; __stkflt : word); + begin + a.flag0:=a.flag0 or ((__stkflt shl bp_fp_status_stkflt) and bm_fp_status_stkflt); + end; + + function errsumm(var a : fp_status) : word; + begin + errsumm:=(a.flag0 and bm_fp_status_errsumm) shr bp_fp_status_errsumm; + end; + + procedure set_errsumm(var a : fp_status; __errsumm : word); + begin + a.flag0:=a.flag0 or ((__errsumm shl bp_fp_status_errsumm) and bm_fp_status_errsumm); + end; + + function c0(var a : fp_status) : word; + begin + c0:=(a.flag0 and bm_fp_status_c0) shr bp_fp_status_c0; + end; + + procedure set_c0(var a : fp_status; __c0 : word); + begin + a.flag0:=a.flag0 or ((__c0 shl bp_fp_status_c0) and bm_fp_status_c0); + end; + + function c1(var a : fp_status) : word; + begin + c1:=(a.flag0 and bm_fp_status_c1) shr bp_fp_status_c1; + end; + + procedure set_c1(var a : fp_status; __c1 : word); + begin + a.flag0:=a.flag0 or ((__c1 shl bp_fp_status_c1) and bm_fp_status_c1); + end; + + function c2(var a : fp_status) : word; + begin + c2:=(a.flag0 and bm_fp_status_c2) shr bp_fp_status_c2; + end; + + procedure set_c2(var a : fp_status; __c2 : word); + begin + a.flag0:=a.flag0 or ((__c2 shl bp_fp_status_c2) and bm_fp_status_c2); + end; + + function tos(var a : fp_status) : word; + begin + tos:=(a.flag0 and bm_fp_status_tos) shr bp_fp_status_tos; + end; + + procedure set_tos(var a : fp_status; __tos : word); + begin + a.flag0:=a.flag0 or ((__tos shl bp_fp_status_tos) and bm_fp_status_tos); + end; + + function c3(var a : fp_status) : word; + begin + c3:=(a.flag0 and bm_fp_status_c3) shr bp_fp_status_c3; + end; + + procedure set_c3(var a : fp_status; __c3 : word); + begin + a.flag0:=a.flag0 or ((__c3 shl bp_fp_status_c3) and bm_fp_status_c3); + end; + + function busy(var a : fp_status) : word; + begin + busy:=(a.flag0 and bm_fp_status_busy) shr bp_fp_status_busy; + end; + + procedure set_busy(var a : fp_status; __busy : word); + begin + a.flag0:=a.flag0 or ((__busy shl bp_fp_status_busy) and bm_fp_status_busy); + end; + +*) + + mcontext_t = record + es: x86_64_exception_state_t; + ss: x86_64_thread_state_t; + fs: x86_64_float_state_t; + end; + + psigcontext = ^sigcontextrec; + psigcontextrec = ^sigcontextrec; + sigcontextrec = record + sc_onstack: cint; + sc_mask: cint; + ts: x86_64_thread_state; + end; diff --git a/rtl/darwin/x86_64/sighnd.inc b/rtl/darwin/x86_64/sighnd.inc new file mode 100644 index 0000000000..50f1632777 --- /dev/null +++ b/rtl/darwin/x86_64/sighnd.inc @@ -0,0 +1,56 @@ +{ + This file is part of the Free Pascal run time library. + (c) 2000-2003 by Marco van de Voort + member of the Free Pascal development team. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + Signalhandler for FreeBSD/i386 + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY;without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +procedure SignalToRunerror(Sig: cint; info : psiginfo; SigContext:PSigContext); cdecl; + +var + res : word; + +begin + res:=0; + case sig of + SIGFPE : + begin + Case Info^.si_code Of + FPE_INTDIV, { integer divide by zero -NOTIMP on Mac OS X 10.4.7 } + FPE_FLTDIV : Res:=200; { floating point divide by zero } + FPE_FLTOVF : Res:=205; { floating point overflow } + FPE_FLTUND : Res:=206; { floating point underflow } + FPE_FLTRES, { floating point inexact result } + FPE_FLTINV : Res:=207; { invalid floating point operation } + Else + Res:=207; { coprocessor error } + end; + { the following is true on ppc, but fortunately not on x86 } + { FPU exceptions are completely disabled by the kernel if one occurred, it } + { seems this is necessary to be able to return to user mode. They can be } + { enabled by executing a sigreturn, however then the exception is triggered } + { triggered again immediately if we don't turn off the "exception occurred" } + { flags in fpscr } + sysResetFPU; + end; + SIGILL, + SIGBUS, + SIGSEGV : + res:=216; + end; + {$ifdef FPC_USE_SIGPROCMASK} + reenable_signal(sig); + {$endif } + + if (res <> 0) then + HandleErrorAddrFrame(res,pointer(sigcontext^.ts.rip),pointer(sigcontext^.ts.rbp)); +end; + diff --git a/rtl/x86_64/math.inc b/rtl/x86_64/math.inc index 00d659f54b..b91802653c 100644 --- a/rtl/x86_64/math.inc +++ b/rtl/x86_64/math.inc @@ -85,6 +85,7 @@ FPC_ABSMASK_DOUBLE: EXTENDED data type routines ****************************************************************************} + {$ifndef FPC_SYSTEM_HAS_PI} {$define FPC_SYSTEM_HAS_PI} function fpc_pi_real : ValReal;compilerproc; begin @@ -92,6 +93,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_PI} + {$ifndef FPC_SYSTEM_HAS_ABS} {$define FPC_SYSTEM_HAS_ABS} function fpc_abs_real(d : ValReal) : ValReal;compilerproc; begin @@ -99,6 +102,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_ABS} + {$ifndef FPC_SYSTEM_HAS_SQR} {$define FPC_SYSTEM_HAS_SQR} function fpc_sqr_real(d : ValReal) : ValReal;compilerproc; begin @@ -106,6 +111,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_SQR} + {$ifndef FPC_SYSTEM_HAS_SQRT} {$define FPC_SYSTEM_HAS_SQRT} function fpc_sqrt_real(d : ValReal) : ValReal;compilerproc; begin @@ -113,6 +120,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_SQRT} + {$ifndef FPC_SYSTEM_HAS_ARCTAN} {$define FPC_SYSTEM_HAS_ARCTAN} function fpc_arctan_real(d : ValReal) : ValReal;compilerproc; begin @@ -120,6 +129,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_ARCTAN} + {$ifndef FPC_SYSTEM_HAS_LN} {$define FPC_SYSTEM_HAS_LN} function fpc_ln_real(d : ValReal) : ValReal;compilerproc; begin @@ -127,6 +138,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_LN} + {$ifndef FPC_SYSTEM_HAS_SIN} {$define FPC_SYSTEM_HAS_SIN} function fpc_sin_real(d : ValReal) : ValReal;compilerproc; begin @@ -134,6 +147,8 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_SIN} + {$ifndef FPC_SYSTEM_HAS_COS} {$define FPC_SYSTEM_HAS_COS} function fpc_cos_real(d : ValReal) : ValReal;compilerproc; begin @@ -141,8 +156,10 @@ FPC_ABSMASK_DOUBLE: runerror(207); result:=0; end; + {$endif FPC_SYSTEM_HAS_COS} {$ifndef WIN64} + {$ifndef FPC_SYSTEM_HAS_EXP} {$define FPC_SYSTEM_HAS_EXP} function fpc_exp_real(d : ValReal) : ValReal;assembler;compilerproc; asm @@ -167,8 +184,10 @@ FPC_ABSMASK_DOUBLE: fscale fstp %st(1) end; + {$endif FPC_SYSTEM_HAS_EXP} + {$ifndef FPC_SYSTEM_HAS_FRAC} {$define FPC_SYSTEM_HAS_FRAC} function fpc_frac_real(d : ValReal) : ValReal;assembler;compilerproc; asm @@ -188,8 +207,10 @@ FPC_ABSMASK_DOUBLE: fnclex fldcw -4(%rbp) end; + {$endif FPC_SYSTEM_HAS_FRAC} + {$ifndef FPC_SYSTEM_HAS_INT} {$define FPC_SYSTEM_HAS_INT} function fpc_int_real(d : ValReal) : ValReal;assembler;compilerproc; asm @@ -206,9 +227,10 @@ FPC_ABSMASK_DOUBLE: fwait fldcw -4(%rbp) end; + {$endif FPC_SYSTEM_HAS_INT} - + {$ifndef FPC_SYSTEM_HAS_TRUNC} {$define FPC_SYSTEM_HAS_TRUNC} function fpc_trunc_real(d : ValReal) : int64;assembler;compilerproc; var @@ -228,8 +250,10 @@ FPC_ABSMASK_DOUBLE: movq res,%rax fldcw oldcw end; + {$endif FPC_SYSTEM_HAS_TRUNC} + {$ifndef FPC_SYSTEM_HAS_ROUND} {$define FPC_SYSTEM_HAS_ROUND} function fpc_round_real(d : ValReal) : int64;assembler;compilerproc; var @@ -240,8 +264,10 @@ FPC_ABSMASK_DOUBLE: fwait movq res,%rax end; + {$endif FPC_SYSTEM_HAS_ROUND} + {$ifndef FPC_SYSTEM_HAS_POWER} {$define FPC_SYSTEM_HAS_POWER} function power(bas,expo : extended) : extended; begin @@ -261,4 +287,5 @@ FPC_ABSMASK_DOUBLE: else power:=exp(ln(bas)*expo); end; + {$endif FPC_SYSTEM_HAS_POWER} {$endif WIN64} diff --git a/rtl/x86_64/strings.inc b/rtl/x86_64/strings.inc index a90ea221ec..6e473b0c3c 100644 --- a/rtl/x86_64/strings.inc +++ b/rtl/x86_64/strings.inc @@ -15,6 +15,7 @@ **********************************************************************} +{$ifndef FPC_UNIT_HAS_STRCOPY} {$define FPC_UNIT_HAS_STRCOPY} { Created from glibc: libc/sysdeps/x86_64/strcpy.S Version 1.2 } function strcopy(dest,source : pchar) : pchar;assembler; @@ -154,8 +155,10 @@ asm movq rdi,%rdi {$endif win64} end; +{$endif FPC_UNIT_HAS_STRCOPY} +{$ifndef FPC_UNIT_HAS_STRCOMP} {$define FPC_UNIT_HAS_STRCOMP} { Created from glibc: libc/sysdeps/x86_64/strcmp.S Version 1.2 } function StrComp(Str1, Str2: PChar): SizeInt;assembler; @@ -192,4 +195,4 @@ asm movq rdi,%rdi {$endif win64} end; - +{$endif FPC_UNIT_HAS_STRCOMP}