953 lines
18 KiB
C++
953 lines
18 KiB
C++
/*
|
|
* compiler/compemu_midfunc_arm.cpp - Native MIDFUNCS for ARM
|
|
*
|
|
* Copyright (c) 2014 Jens Heitmann of ARAnyM dev team (see AUTHORS)
|
|
*
|
|
* Inspired by Christian Bauer's Basilisk II
|
|
*
|
|
* Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer
|
|
*
|
|
* Adaptation for Basilisk II and improvements, copyright 2000-2002
|
|
* Gwenole Beauchesne
|
|
*
|
|
* Basilisk II (C) 1997-2002 Christian Bauer
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* Note:
|
|
* File is included by compemu_support.cpp
|
|
*
|
|
*/
|
|
|
|
/********************************************************************
|
|
* CPU functions exposed to gencomp. Both CREATE and EMIT time *
|
|
********************************************************************/
|
|
|
|
/*
|
|
* RULES FOR HANDLING REGISTERS:
|
|
*
|
|
* * In the function headers, order the parameters
|
|
* - 1st registers written to
|
|
* - 2nd read/modify/write registers
|
|
* - 3rd registers read from
|
|
* * Before calling raw_*, you must call readreg, writereg or rmw for
|
|
* each register
|
|
* * The order for this is
|
|
* - 1nd call readreg for all registers read without offset
|
|
* - 2rd call rmw for all rmw registers
|
|
* - 3th call writereg for all written-to registers
|
|
* - 4th call raw_*
|
|
* - 5th unlock2 all registers that were locked
|
|
*/
|
|
|
|
MIDFUNC(0,live_flags,(void))
|
|
{
|
|
live.flags_on_stack = TRASH;
|
|
live.flags_in_flags = VALID;
|
|
live.flags_are_important = 1;
|
|
}
|
|
MENDFUNC(0,live_flags,(void))
|
|
|
|
MIDFUNC(0,dont_care_flags,(void))
|
|
{
|
|
live.flags_are_important = 0;
|
|
}
|
|
MENDFUNC(0,dont_care_flags,(void))
|
|
|
|
MIDFUNC(0,make_flags_live,(void))
|
|
{
|
|
make_flags_live_internal();
|
|
}
|
|
MENDFUNC(0,make_flags_live,(void))
|
|
|
|
MIDFUNC(2,mov_l_mi,(IMM d, IMM s))
|
|
{
|
|
raw_mov_l_mi(d, s);
|
|
}
|
|
MENDFUNC(2,mov_l_mi,(IMM d, IMM s))
|
|
|
|
MIDFUNC(2,shll_l_ri,(RW4 r, IMM i))
|
|
{
|
|
// Only used in calc_disp_ea_020() -> flags not relevant and never modified
|
|
if (!i)
|
|
return;
|
|
if (isconst(r)) {
|
|
live.state[r].val<<=i;
|
|
return;
|
|
}
|
|
|
|
r = rmw(r, 4, 4);
|
|
raw_shll_l_ri(r, i);
|
|
unlock2(r);
|
|
}
|
|
MENDFUNC(2,shll_l_ri,(RW4 r, IMM i))
|
|
|
|
MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s))
|
|
{
|
|
// Only used in calc_disp_ea_020() -> flags not relevant and never modified
|
|
int isrmw;
|
|
|
|
if (isconst(s)) {
|
|
set_const(d, (uae_s32)(uae_s16)live.state[s].val);
|
|
return;
|
|
}
|
|
|
|
isrmw = (s == d);
|
|
if (!isrmw) {
|
|
s = readreg(s, 2);
|
|
d = writereg(d, 4);
|
|
}
|
|
else { /* If we try to lock this twice, with different sizes, we are in trouble! */
|
|
s = d = rmw(s, 4, 2);
|
|
}
|
|
SIGNED16_REG_2_REG(d, s);
|
|
if (!isrmw) {
|
|
unlock2(d);
|
|
unlock2(s);
|
|
}
|
|
else {
|
|
unlock2(s);
|
|
}
|
|
}
|
|
MENDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s))
|
|
|
|
MIDFUNC(2,mov_b_rr,(W1 d, RR1 s))
|
|
{
|
|
if (d == s)
|
|
return;
|
|
if (isconst(s)) {
|
|
COMPCALL(mov_b_ri)(d, (uae_u8)live.state[s].val);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 1);
|
|
d = writereg(d, 1);
|
|
raw_mov_b_rr(d, s);
|
|
unlock2(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,mov_b_rr,(W1 d, RR1 s))
|
|
|
|
MIDFUNC(2,mov_w_rr,(W2 d, RR2 s))
|
|
{
|
|
if (d == s)
|
|
return;
|
|
if (isconst(s)) {
|
|
COMPCALL(mov_w_ri)(d, (uae_u16)live.state[s].val);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 2);
|
|
d = writereg(d, 2);
|
|
raw_mov_w_rr(d, s);
|
|
unlock2(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,mov_w_rr,(W2 d, RR2 s))
|
|
|
|
MIDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset))
|
|
{
|
|
if (isconst(s)) {
|
|
COMPCALL(mov_l_ri)(d, live.state[s].val+offset);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 4);
|
|
d = writereg(d, 4);
|
|
raw_lea_l_brr(d, s, offset);
|
|
unlock2(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset))
|
|
|
|
MIDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset))
|
|
{
|
|
if (!offset) {
|
|
COMPCALL(lea_l_rr_indexed)(d, s, index, factor);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 4);
|
|
index = readreg(index, 4);
|
|
d = writereg(d, 4);
|
|
raw_lea_l_brr_indexed(d, s, index, factor, offset);
|
|
unlock2(d);
|
|
unlock2(index);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset))
|
|
|
|
MIDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor))
|
|
{
|
|
s = readreg(s, 4);
|
|
index = readreg(index, 4);
|
|
d = writereg(d, 4);
|
|
raw_lea_l_rr_indexed(d, s, index, factor);
|
|
unlock2(d);
|
|
unlock2(index);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor))
|
|
|
|
MIDFUNC(2,mov_l_rr,(W4 d, RR4 s))
|
|
{
|
|
int olds;
|
|
|
|
if (d == s) { /* How pointless! */
|
|
return;
|
|
}
|
|
if (isconst(s)) {
|
|
COMPCALL(mov_l_ri)(d, live.state[s].val);
|
|
return;
|
|
}
|
|
olds = s;
|
|
disassociate(d);
|
|
s = readreg(s, 4);
|
|
live.state[d].realreg = s;
|
|
live.state[d].realind = live.nat[s].nholds;
|
|
live.state[d].val = live.state[olds].val;
|
|
live.state[d].validsize = 4;
|
|
live.state[d].dirtysize = 4;
|
|
set_status(d, DIRTY);
|
|
|
|
live.nat[s].holds[live.nat[s].nholds] = d;
|
|
live.nat[s].nholds++;
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,mov_l_rr,(W4 d, RR4 s))
|
|
|
|
MIDFUNC(2,mov_l_mr,(IMM d, RR4 s))
|
|
{
|
|
if (isconst(s)) {
|
|
COMPCALL(mov_l_mi)(d, live.state[s].val);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 4);
|
|
raw_mov_l_mr(d, s);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,mov_l_mr,(IMM d, RR4 s))
|
|
|
|
MIDFUNC(2,mov_l_rm,(W4 d, IMM s))
|
|
{
|
|
d = writereg(d, 4);
|
|
raw_mov_l_rm(d, s);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,mov_l_rm,(W4 d, IMM s))
|
|
|
|
MIDFUNC(2,mov_l_ri,(W4 d, IMM s))
|
|
{
|
|
set_const(d, s);
|
|
return;
|
|
}
|
|
MENDFUNC(2,mov_l_ri,(W4 d, IMM s))
|
|
|
|
MIDFUNC(2,mov_w_ri,(W2 d, IMM s))
|
|
{
|
|
d = writereg(d, 2);
|
|
raw_mov_w_ri(d, s);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,mov_w_ri,(W2 d, IMM s))
|
|
|
|
MIDFUNC(2,mov_b_ri,(W1 d, IMM s))
|
|
{
|
|
d = writereg(d, 1);
|
|
raw_mov_b_ri(d, s);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,mov_b_ri,(W1 d, IMM s))
|
|
|
|
MIDFUNC(2,add_l,(RW4 d, RR4 s))
|
|
{
|
|
if (isconst(s)) {
|
|
COMPCALL(add_l_ri)(d, live.state[s].val);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 4);
|
|
d = rmw(d, 4, 4);
|
|
raw_add_l(d, s);
|
|
unlock2(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,add_l,(RW4 d, RR4 s))
|
|
|
|
MIDFUNC(2,sub_l_ri,(RW4 d, IMM i))
|
|
{
|
|
if (!i)
|
|
return;
|
|
if (isconst(d)) {
|
|
live.state[d].val -= i;
|
|
return;
|
|
}
|
|
|
|
d = rmw(d, 4, 4);
|
|
raw_sub_l_ri(d, i);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,sub_l_ri,(RW4 d, IMM i))
|
|
|
|
MIDFUNC(2,sub_w_ri,(RW2 d, IMM i))
|
|
{
|
|
// Caller needs flags...
|
|
clobber_flags();
|
|
|
|
d = rmw(d, 2, 2);
|
|
raw_sub_w_ri(d, i);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,sub_w_ri,(RW2 d, IMM i))
|
|
|
|
MIDFUNC(2,add_l_ri,(RW4 d, IMM i))
|
|
{
|
|
if (!i)
|
|
return;
|
|
if (isconst(d)) {
|
|
live.state[d].val += i;
|
|
return;
|
|
}
|
|
|
|
d = rmw(d, 4, 4);
|
|
raw_add_l_ri(d, i);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,add_l_ri,(RW4 d, IMM i))
|
|
|
|
MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
|
|
{
|
|
clobber_flags();
|
|
in1 = readreg_specific(in1, isize1, REG_PAR1);
|
|
in2 = readreg_specific(in2, isize2, REG_PAR2);
|
|
r = readreg(r, 4);
|
|
prepare_for_call_1();
|
|
unlock2(r);
|
|
unlock2(in1);
|
|
unlock2(in2);
|
|
prepare_for_call_2();
|
|
compemu_raw_call_r(r);
|
|
}
|
|
MENDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
|
|
|
|
MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
|
|
{
|
|
clobber_flags();
|
|
if (osize == 4) {
|
|
if (out1 != in1 && out1 != r) {
|
|
COMPCALL(forget_about)(out1);
|
|
}
|
|
}
|
|
else {
|
|
tomem_c(out1);
|
|
}
|
|
|
|
in1 = readreg_specific(in1, isize, REG_PAR1);
|
|
r = readreg(r, 4);
|
|
prepare_for_call_1();
|
|
|
|
unlock2(in1);
|
|
unlock2(r);
|
|
|
|
prepare_for_call_2();
|
|
compemu_raw_call_r(r);
|
|
|
|
live.nat[REG_RESULT].holds[0] = out1;
|
|
live.nat[REG_RESULT].nholds = 1;
|
|
live.nat[REG_RESULT].touched = touchcnt++;
|
|
|
|
live.state[out1].realreg = REG_RESULT;
|
|
live.state[out1].realind = 0;
|
|
live.state[out1].val = 0;
|
|
live.state[out1].validsize = osize;
|
|
live.state[out1].dirtysize = osize;
|
|
set_status(out1, DIRTY);
|
|
}
|
|
MENDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
|
|
|
|
/* forget_about() takes a mid-layer register */
|
|
MIDFUNC(1,forget_about,(W4 r))
|
|
{
|
|
if (isinreg(r))
|
|
disassociate(r);
|
|
live.state[r].val = 0;
|
|
set_status(r, UNDEF);
|
|
}
|
|
MENDFUNC(1,forget_about,(W4 r))
|
|
|
|
|
|
// ARM optimized functions
|
|
|
|
MIDFUNC(2,arm_ADD_l,(RW4 d, RR4 s))
|
|
{
|
|
if (isconst(s)) {
|
|
COMPCALL(arm_ADD_l_ri)(d,live.state[s].val);
|
|
return;
|
|
}
|
|
|
|
s = readreg(s, 4);
|
|
d = rmw(d, 4, 4);
|
|
raw_ADD_l_rr(d, s);
|
|
unlock2(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,arm_ADD_l,(RW4 d, RR4 s))
|
|
|
|
MIDFUNC(2,arm_ADD_l_ri,(RW4 d, IMM i))
|
|
{
|
|
if (!i)
|
|
return;
|
|
if (isconst(d)) {
|
|
live.state[d].val += i;
|
|
return;
|
|
}
|
|
|
|
d = rmw(d, 4, 4);
|
|
|
|
if(CHECK32(i)) {
|
|
raw_ADD_l_rri(d, d, i);
|
|
} else {
|
|
raw_LDR_l_ri(REG_WORK1, i);
|
|
raw_ADD_l_rr(d, REG_WORK1);
|
|
}
|
|
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,arm_ADD_l_ri,(RW4 d, IMM i))
|
|
|
|
MIDFUNC(2,arm_ADD_l_ri8,(RW4 d, IMM i))
|
|
{
|
|
if (!i)
|
|
return;
|
|
if (isconst(d)) {
|
|
live.state[d].val += i;
|
|
return;
|
|
}
|
|
|
|
d = rmw(d, 4, 4);
|
|
raw_ADD_l_rri(d, d, i);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,arm_ADD_l_ri8,(RW4 d, IMM i))
|
|
|
|
MIDFUNC(2,arm_SUB_l_ri8,(RW4 d, IMM i))
|
|
{
|
|
if (!i)
|
|
return;
|
|
if (isconst(d)) {
|
|
live.state[d].val -= i;
|
|
return;
|
|
}
|
|
|
|
d = rmw(d, 4, 4);
|
|
raw_SUB_l_rri(d, d, i);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,arm_SUB_l_ri8,(RW4 d, IMM i))
|
|
|
|
|
|
// Other
|
|
STATIC_INLINE void flush_cpu_icache(void *start, void *stop)
|
|
{
|
|
register void *_beg __asm ("a1") = start;
|
|
register void *_end __asm ("a2") = stop;
|
|
register void *_flg __asm ("a3") = 0;
|
|
#ifdef __ARM_EABI__
|
|
register unsigned long _scno __asm ("r7") = 0xf0002;
|
|
__asm __volatile ("swi 0x0 @ sys_cacheflush"
|
|
: "=r" (_beg)
|
|
: "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno));
|
|
#else
|
|
__asm __volatile ("swi 0x9f0002 @ sys_cacheflush"
|
|
: "=r" (_beg)
|
|
: "0" (_beg), "r" (_end), "r" (_flg));
|
|
#endif
|
|
}
|
|
|
|
STATIC_INLINE void write_jmp_target(uae_u32* jmpaddr, uintptr a) {
|
|
uae_s32 off = ((uae_u32)a - (uae_u32)jmpaddr - 8) >> 2;
|
|
*(jmpaddr) = (*(jmpaddr) & 0xff000000) | (off & 0x00ffffff);
|
|
flush_cpu_icache((void *)jmpaddr, (void *)&jmpaddr[1]);
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* FPU stuff *
|
|
*************************************************************************/
|
|
|
|
MIDFUNC(1,f_forget_about,(FW r))
|
|
{
|
|
if (f_isinreg(r))
|
|
f_disassociate(r);
|
|
live.fate[r].status=UNDEF;
|
|
}
|
|
MENDFUNC(1,f_forget_about,(FW r))
|
|
|
|
MIDFUNC(0,dont_care_fflags,(void))
|
|
{
|
|
f_disassociate(FP_RESULT);
|
|
}
|
|
MENDFUNC(0,dont_care_fflags,(void))
|
|
|
|
MIDFUNC(2,fmov_rr,(FW d, FR s))
|
|
{
|
|
if (d == s) { /* How pointless! */
|
|
return;
|
|
}
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_fmov_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fmov_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(2,fmov_l_rr,(FW d, RR4 s))
|
|
{
|
|
s = readreg(s, 4);
|
|
d = f_writereg(d);
|
|
raw_fmov_l_rr(d, s);
|
|
f_unlock(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,fmov_l_rr,(FW d, RR4 s))
|
|
|
|
MIDFUNC(2,fmov_s_rr,(FW d, RR4 s))
|
|
{
|
|
s = readreg(s, 4);
|
|
d = f_writereg(d);
|
|
raw_fmov_s_rr(d, s);
|
|
f_unlock(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,fmov_s_rr,(FW d, RR4 s))
|
|
|
|
MIDFUNC(2,fmov_w_rr,(FW d, RR2 s))
|
|
{
|
|
s = readreg(s, 2);
|
|
d = f_writereg(d);
|
|
raw_fmov_w_rr(d, s);
|
|
f_unlock(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,fmov_w_rr,(FW d, RR2 s))
|
|
|
|
MIDFUNC(2,fmov_b_rr,(FW d, RR1 s))
|
|
{
|
|
s = readreg(s, 1);
|
|
d = f_writereg(d);
|
|
raw_fmov_b_rr(d, s);
|
|
f_unlock(d);
|
|
unlock2(s);
|
|
}
|
|
MENDFUNC(2,fmov_b_rr,(FW d, RR1 s))
|
|
|
|
MIDFUNC(3,fmov_d_rrr,(FW d, RR4 s1, RR4 s2))
|
|
{
|
|
s1 = readreg(s1, 4);
|
|
s2 = readreg(s2, 4);
|
|
d = f_writereg(d);
|
|
raw_fmov_d_rrr(d, s1, s2);
|
|
f_unlock(d);
|
|
unlock2(s2);
|
|
unlock2(s1);
|
|
}
|
|
MENDFUNC(3,fmov_d_rrr,(FW d, RR4 s1, RR4 s2))
|
|
|
|
MIDFUNC(2,fmov_l_ri,(FW d, IMM i))
|
|
{
|
|
switch(i) {
|
|
case 0:
|
|
fmov_d_ri_0(d);
|
|
break;
|
|
case 1:
|
|
fmov_d_ri_1(d);
|
|
break;
|
|
case 10:
|
|
fmov_d_ri_10(d);
|
|
break;
|
|
case 100:
|
|
fmov_d_ri_100(d);
|
|
break;
|
|
default:
|
|
d = f_writereg(d);
|
|
compemu_raw_mov_l_ri(REG_WORK1, i);
|
|
raw_fmov_l_rr(d, REG_WORK1);
|
|
f_unlock(d);
|
|
}
|
|
}
|
|
MENDFUNC(2,fmov_l_ri,(FW d, IMM i))
|
|
|
|
MIDFUNC(2,fmov_s_ri,(FW d, IMM i))
|
|
{
|
|
d = f_writereg(d);
|
|
compemu_raw_mov_l_ri(REG_WORK1, i);
|
|
raw_fmov_s_rr(d, REG_WORK1);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fmov_s_ri,(FW d, IMM i))
|
|
|
|
MIDFUNC(2,fmov_to_l_rr,(W4 d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = writereg(d, 4);
|
|
raw_fmov_to_l_rr(d, s);
|
|
unlock2(d);
|
|
f_unlock(s);
|
|
}
|
|
MENDFUNC(2,fmov_to_l_rr,(W4 d, FR s))
|
|
|
|
MIDFUNC(2,fmov_to_s_rr,(W4 d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = writereg(d, 4);
|
|
raw_fmov_to_s_rr(d, s);
|
|
unlock2(d);
|
|
f_unlock(s);
|
|
}
|
|
MENDFUNC(2,fmov_to_s_rr,(W4 d, FR s))
|
|
|
|
MIDFUNC(2,fmov_to_w_rr,(W4 d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = writereg(d, 2);
|
|
raw_fmov_to_w_rr(d, s);
|
|
unlock2(d);
|
|
f_unlock(s);
|
|
}
|
|
MENDFUNC(2,fmov_to_w_rr,(W4 d, FR s))
|
|
|
|
MIDFUNC(2,fmov_to_b_rr,(W4 d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = writereg(d, 1);
|
|
raw_fmov_to_b_rr(d, s);
|
|
unlock2(d);
|
|
f_unlock(s);
|
|
}
|
|
MENDFUNC(2,fmov_to_b_rr,(W4 d, FR s))
|
|
|
|
MIDFUNC(1,fmov_d_ri_0,(FW r))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmov_d_ri_0(r);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(1,fmov_d_ri_0,(FW r))
|
|
|
|
MIDFUNC(1,fmov_d_ri_1,(FW r))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmov_d_ri_1(r);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(1,fmov_d_ri_1,(FW r))
|
|
|
|
MIDFUNC(1,fmov_d_ri_10,(FW r))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmov_d_ri_10(r);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(1,fmov_d_ri_10,(FW r))
|
|
|
|
MIDFUNC(1,fmov_d_ri_100,(FW r))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmov_d_ri_100(r);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(1,fmov_d_ri_100,(FW r))
|
|
|
|
MIDFUNC(2,fmov_d_rm,(FW r, MEMR m))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmov_d_rm(r, m);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(2,fmov_d_rm,(FW r, MEMR m))
|
|
|
|
MIDFUNC(2,fmovs_rm,(FW r, MEMR m))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmovs_rm(r, m);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(2,fmovs_rm,(FW r, MEMR m))
|
|
|
|
MIDFUNC(2,fmov_rm,(FW r, MEMR m))
|
|
{
|
|
r = f_writereg(r);
|
|
raw_fmov_d_rm(r, m);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(2,fmov_rm,(FW r, MEMR m))
|
|
|
|
MIDFUNC(3,fmov_to_d_rrr,(W4 d1, W4 d2, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d1 = writereg(d1, 4);
|
|
d2 = writereg(d2, 4);
|
|
raw_fmov_to_d_rrr(d1, d2, s);
|
|
unlock2(d2);
|
|
unlock2(d1);
|
|
f_unlock(s);
|
|
}
|
|
MENDFUNC(3,fmov_to_d_rrr,(W4 d1, W4 d2, FR s))
|
|
|
|
MIDFUNC(2,fsqrt_rr,(FW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_fsqrt_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fsqrt_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(2,fabs_rr,(FW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_fabs_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fabs_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(2,fneg_rr,(FW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_fneg_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fneg_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(2,fdiv_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fdiv_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fdiv_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,fadd_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fadd_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fadd_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,fmul_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fmul_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fmul_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,fsub_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fsub_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fsub_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,frndint_rr,(FW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_frndint_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,frndint_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(2,frndintz_rr,(FW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_frndintz_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,frndintz_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(2,fmod_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fmod_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fmod_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,fsgldiv_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fsgldiv_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fsgldiv_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(1,fcuts_r,(FRW r))
|
|
{
|
|
r = f_rmw(r);
|
|
raw_fcuts_r(r);
|
|
f_unlock(r);
|
|
}
|
|
MENDFUNC(1,fcuts_r,(FRW r))
|
|
|
|
MIDFUNC(2,frem1_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_frem1_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,frem1_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,fsglmul_rr,(FRW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_rmw(d);
|
|
raw_fsglmul_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fsglmul_rr,(FRW d, FR s))
|
|
|
|
MIDFUNC(2,fmovs_rr,(FW d, FR s))
|
|
{
|
|
s = f_readreg(s);
|
|
d = f_writereg(d);
|
|
raw_fmovs_rr(d, s);
|
|
f_unlock(s);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fmovs_rr,(FW d, FR s))
|
|
|
|
MIDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s))
|
|
{
|
|
clobber_flags();
|
|
|
|
s = f_readreg(s);
|
|
int reald = f_writereg(d);
|
|
|
|
prepare_for_call_1();
|
|
|
|
f_unlock(s);
|
|
f_unlock(reald);
|
|
|
|
prepare_for_call_2();
|
|
|
|
raw_ffunc_rr(func, reald, s);
|
|
|
|
live.fat[reald].holds = d;
|
|
live.fat[reald].nholds = 1;
|
|
|
|
live.fate[d].realreg = reald;
|
|
live.fate[d].status = DIRTY;
|
|
}
|
|
MENDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s))
|
|
|
|
MIDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s))
|
|
{
|
|
clobber_flags();
|
|
|
|
s = f_readreg(s);
|
|
int reald = f_writereg(d);
|
|
|
|
prepare_for_call_1();
|
|
|
|
f_unlock(s);
|
|
f_unlock(reald);
|
|
|
|
prepare_for_call_2();
|
|
|
|
raw_fpowx_rr(x, reald, s);
|
|
|
|
live.fat[reald].holds = d;
|
|
live.fat[reald].nholds = 1;
|
|
|
|
live.fate[d].realreg = reald;
|
|
live.fate[d].status = DIRTY;
|
|
}
|
|
MENDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s))
|
|
|
|
MIDFUNC(1,fflags_into_flags,())
|
|
{
|
|
clobber_flags();
|
|
fflags_into_flags_internal();
|
|
}
|
|
MENDFUNC(1,fflags_into_flags,())
|
|
|
|
MIDFUNC(2,fp_from_exten_mr,(RR4 adr, FR s))
|
|
{
|
|
clobber_flags();
|
|
|
|
adr = readreg(adr, 4);
|
|
s = f_readreg(s);
|
|
raw_fp_from_exten_mr(adr, s);
|
|
f_unlock(s);
|
|
unlock2(adr);
|
|
}
|
|
MENDFUNC(2,fp_from_exten_mr,(RR4 adr, FR s))
|
|
|
|
MIDFUNC(2,fp_to_exten_rm,(FW d, RR4 adr))
|
|
{
|
|
clobber_flags();
|
|
|
|
adr = readreg(adr, 4);
|
|
d = f_writereg(d);
|
|
raw_fp_to_exten_rm(d, adr);
|
|
unlock2(adr);
|
|
f_unlock(d);
|
|
}
|
|
MENDFUNC(2,fp_to_exten_rm,(FW d, RR4 adr))
|
|
|
|
MIDFUNC(2,fp_fscc_ri,(RW4 d, int cc))
|
|
{
|
|
d = rmw(d, 4, 4);
|
|
raw_fp_fscc_ri(d, cc);
|
|
unlock2(d);
|
|
}
|
|
MENDFUNC(2,fp_fscc_ri,(RW4 d, int cc))
|
|
|
|
MIDFUNC(1,roundingmode,(IMM mode))
|
|
{
|
|
raw_roundingmode(mode);
|
|
}
|
|
MENDFUNC(1,roundingmode,(IMM mode))
|
|
|
|
|
|
|