Merge remote-tracking branch 'remotes/vivier/tags/m68k-next-pull-request' into staging

remove m68k simulator syscall interface
Fix comments format
Fix gdbstub

# gpg: Signature made Wed 26 Jun 2019 17:20:41 BST
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier/tags/m68k-next-pull-request:
  linux-user/m68k: remove simulator syscall interface
  m68k comments break patch submission due to being incorrectly formatted
  The m68k gdbstub SR reg request doesnt include Condition-Codes

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2019-07-01 16:59:29 +01:00
17 changed files with 356 additions and 411 deletions
-1
View File
@@ -8,4 +8,3 @@ obj-$(TARGET_I386) += vm86.o
obj-$(TARGET_ARM) += arm/nwfpe/
obj-$(TARGET_ARM) += arm/semihost.o
obj-$(TARGET_AARCH64) += arm/semihost.o
obj-$(TARGET_M68K) += m68k-sim.o
-163
View File
@@ -1,163 +0,0 @@
/*
* m68k simulator syscall interface
*
* Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu.h"
#define SYS_EXIT 1
#define SYS_READ 3
#define SYS_WRITE 4
#define SYS_OPEN 5
#define SYS_CLOSE 6
#define SYS_BRK 17
#define SYS_FSTAT 28
#define SYS_ISATTY 29
#define SYS_LSEEK 199
struct m68k_sim_stat {
uint16_t sim_st_dev;
uint16_t sim_st_ino;
uint32_t sim_st_mode;
uint16_t sim_st_nlink;
uint16_t sim_st_uid;
uint16_t sim_st_gid;
uint16_t sim_st_rdev;
uint32_t sim_st_size;
uint32_t sim_st_atime;
uint32_t sim_st_mtime;
uint32_t sim_st_ctime;
uint32_t sim_st_blksize;
uint32_t sim_st_blocks;
};
static inline uint32_t check_err(CPUM68KState *env, uint32_t code)
{
env->dregs[0] = code;
if (code == (uint32_t)-1) {
env->dregs[1] = errno;
} else {
env->dregs[1] = 0;
}
return code;
}
#define SIM_O_APPEND 0x0008
#define SIM_O_CREAT 0x0200
#define SIM_O_TRUNC 0x0400
#define SIM_O_EXCL 0x0800
#define SIM_O_NONBLOCK 0x4000
#define SIM_O_NOCTTY 0x8000
#define SIM_O_SYNC 0x2000
static int translate_openflags(int flags)
{
int hf;
switch (flags & 3) {
case 0: hf = O_RDONLY; break;
case 1: hf = O_WRONLY; break;
case 2: hf = O_RDWR; break;
default: hf = O_RDWR; break;
}
if (flags & SIM_O_APPEND) hf |= O_APPEND;
if (flags & SIM_O_CREAT) hf |= O_CREAT;
if (flags & SIM_O_TRUNC) hf |= O_TRUNC;
if (flags & SIM_O_EXCL) hf |= O_EXCL;
if (flags & SIM_O_NONBLOCK) hf |= O_NONBLOCK;
if (flags & SIM_O_NOCTTY) hf |= O_NOCTTY;
if (flags & SIM_O_SYNC) hf |= O_SYNC;
return hf;
}
#define ARG(x) tswap32(args[x])
void do_m68k_simcall(CPUM68KState *env, int nr)
{
uint32_t *args;
args = (uint32_t *)(unsigned long)(env->aregs[7] + 4);
switch (nr) {
case SYS_EXIT:
exit(ARG(0));
case SYS_READ:
check_err(env, read(ARG(0), (void *)(unsigned long)ARG(1), ARG(2)));
break;
case SYS_WRITE:
check_err(env, write(ARG(0), (void *)(unsigned long)ARG(1), ARG(2)));
break;
case SYS_OPEN:
check_err(env, open((char *)(unsigned long)ARG(0),
translate_openflags(ARG(1)), ARG(2)));
break;
case SYS_CLOSE:
{
/* Ignore attempts to close stdin/out/err. */
int fd = ARG(0);
if (fd > 2)
check_err(env, close(fd));
else
check_err(env, 0);
break;
}
case SYS_BRK:
{
int32_t ret;
ret = do_brk((abi_ulong)ARG(0));
if (ret == -ENOMEM)
ret = -1;
check_err(env, ret);
}
break;
case SYS_FSTAT:
{
struct stat s;
int rc;
struct m68k_sim_stat *p;
rc = check_err(env, fstat(ARG(0), &s));
if (rc == 0) {
p = (struct m68k_sim_stat *)(unsigned long)ARG(1);
p->sim_st_dev = tswap16(s.st_dev);
p->sim_st_ino = tswap16(s.st_ino);
p->sim_st_mode = tswap32(s.st_mode);
p->sim_st_nlink = tswap16(s.st_nlink);
p->sim_st_uid = tswap16(s.st_uid);
p->sim_st_gid = tswap16(s.st_gid);
p->sim_st_rdev = tswap16(s.st_rdev);
p->sim_st_size = tswap32(s.st_size);
p->sim_st_atime = tswap32(s.st_atime);
p->sim_st_mtime = tswap32(s.st_mtime);
p->sim_st_ctime = tswap32(s.st_ctime);
p->sim_st_blksize = tswap32(s.st_blksize);
p->sim_st_blocks = tswap32(s.st_blocks);
}
}
break;
case SYS_ISATTY:
check_err(env, isatty(ARG(0)));
break;
case SYS_LSEEK:
check_err(env, lseek(ARG(0), (int32_t)ARG(1), ARG(2)));
break;
default:
cpu_abort(env_cpu(env), "Unsupported m68k sim syscall %d\n", nr);
}
}
+1 -16
View File
@@ -28,7 +28,6 @@ void cpu_loop(CPUM68KState *env)
int trapnr;
unsigned int n;
target_siginfo_t info;
TaskState *ts = cs->opaque;
for(;;) {
cpu_exec_start(cs);
@@ -37,26 +36,14 @@ void cpu_loop(CPUM68KState *env)
process_queued_cpu_work(cs);
switch(trapnr) {
case EXCP_ILLEGAL:
{
if (ts->sim_syscalls) {
uint16_t nr;
get_user_u16(nr, env->pc + 2);
env->pc += 4;
do_m68k_simcall(env, nr);
} else {
goto do_sigill;
}
}
break;
case EXCP_HALT_INSN:
/* Semihosing syscall. */
env->pc += 4;
do_m68k_semihosting(env, env->dregs[0]);
break;
case EXCP_ILLEGAL:
case EXCP_LINEA:
case EXCP_LINEF:
do_sigill:
info.si_signo = TARGET_SIGILL;
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPN;
@@ -80,7 +67,6 @@ void cpu_loop(CPUM68KState *env)
case EXCP_TRAP0:
{
abi_long ret;
ts->sim_syscalls = 0;
n = env->dregs[0];
env->pc += 2;
ret = do_syscall(env,
@@ -154,7 +140,6 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
env->aregs[7] = regs->usp;
env->sr = regs->sr;
ts->sim_syscalls = 1;
ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
-2
View File
@@ -26,6 +26,4 @@ struct target_pt_regs {
#define TARGET_WANT_OLD_SYS_SELECT
void do_m68k_simcall(CPUM68KState *, int);
#endif /* M68K_TARGET_SYSCALL_H */
-1
View File
@@ -116,7 +116,6 @@ typedef struct TaskState {
#endif
abi_ulong child_tidptr;
#ifdef TARGET_M68K
int sim_syscalls;
abi_ulong tp_value;
#endif
#if defined(TARGET_ARM) || defined(TARGET_M68K)
+1 -1
View File
@@ -31,7 +31,7 @@
#define M68K_CPU_GET_CLASS(obj) \
OBJECT_GET_CLASS(M68kCPUClass, (obj), TYPE_M68K_CPU)
/**
/*
* M68kCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
+4 -2
View File
@@ -203,8 +203,10 @@ static void any_cpu_initfn(Object *obj)
m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
m68k_set_feature(env, M68K_FEATURE_BRAL);
m68k_set_feature(env, M68K_FEATURE_CF_FPU);
/* MAC and EMAC are mututally exclusive, so pick EMAC.
It's mostly backwards compatible. */
/*
* MAC and EMAC are mututally exclusive, so pick EMAC.
* It's mostly backwards compatible.
*/
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
m68k_set_feature(env, M68K_FEATURE_USP);
+18 -11
View File
@@ -106,9 +106,11 @@ typedef struct CPUM68KState {
float_status fp_status;
uint64_t mactmp;
/* EMAC Hardware deals with 48-bit values composed of one 32-bit and
two 8-bit parts. We store a single 64-bit value and
rearrange/extend this when changing modes. */
/*
* EMAC Hardware deals with 48-bit values composed of one 32-bit and
* two 8-bit parts. We store a single 64-bit value and
* rearrange/extend this when changing modes.
*/
uint64_t macc[4];
uint32_t macsr;
uint32_t mac_mask;
@@ -146,7 +148,7 @@ typedef struct CPUM68KState {
uint32_t features;
} CPUM68KState;
/**
/*
* M68kCPU:
* @env: #CPUM68KState
*
@@ -171,9 +173,11 @@ int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void m68k_tcg_init(void);
void m68k_cpu_init_gdb(M68kCPU *cpu);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
/*
* you can call this signal handler from your SIGBUS and SIGSEGV
* signal handlers to inform the virtual CPU of exceptions. non zero
* is returned if the signal was handled by the virtual CPU.
*/
int cpu_m68k_signal_handler(int host_signum, void *pinfo,
void *puc);
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
@@ -182,7 +186,8 @@ void cpu_m68k_set_sr(CPUM68KState *env, uint32_t);
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val);
/* Instead of computing the condition codes after each m68k instruction,
/*
* Instead of computing the condition codes after each m68k instruction,
* QEMU just stores one operand (called CC_SRC), the result
* (called CC_DEST) and the type of operation (called CC_OP). When the
* condition codes are needed, the condition codes can be calculated
@@ -447,9 +452,11 @@ void m68k_switch_sp(CPUM68KState *env);
void do_m68k_semihosting(CPUM68KState *env, int nr);
/* There are 4 ColdFire core ISA revisions: A, A+, B and C.
Each feature covers the subset of instructions common to the
ISA revisions mentioned. */
/*
* There are 4 ColdFire core ISA revisions: A, A+, B and C.
* Each feature covers the subset of instructions common to the
* ISA revisions mentioned.
*/
enum m68k_features {
M68K_FEATURE_M68000,
+4 -2
View File
@@ -25,7 +25,8 @@
#include "exec/cpu_ldst.h"
#include "softfloat.h"
/* Undefined offsets may be different on various FPU.
/*
* Undefined offsets may be different on various FPU.
* On 68040 they return 0.0 (floatx80_zero)
*/
@@ -611,7 +612,8 @@ void HELPER(fcos)(CPUM68KState *env, FPReg *res, FPReg *val)
void HELPER(fsincos)(CPUM68KState *env, FPReg *res0, FPReg *res1, FPReg *val)
{
floatx80 a = val->d;
/* If res0 and res1 specify the same floating-point data register,
/*
* If res0 and res1 specify the same floating-point data register,
* the sine result is stored in the register, and the cosine
* result is discarded.
*/
+6 -3
View File
@@ -35,13 +35,16 @@ int m68k_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
} else {
switch (n) {
case 16:
return gdb_get_reg32(mem_buf, env->sr);
/* SR is made of SR+CCR, CCR is many 1bit flags so uses helper */
return gdb_get_reg32(mem_buf, env->sr | cpu_m68k_get_ccr(env));
case 17:
return gdb_get_reg32(mem_buf, env->pc);
}
}
/* FP registers not included here because they vary between
ColdFire and m68k. Use XML bits for these. */
/*
* FP registers not included here because they vary between
* ColdFire and m68k. Use XML bits for these.
*/
return 0;
}
+10 -6
View File
@@ -965,9 +965,11 @@ void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
}
/* MAC unit. */
/* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
take values, others take register numbers and manipulate the contents
in-place. */
/*
* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
* take values, others take register numbers and manipulate the contents
* in-place.
*/
void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
{
uint32_t mask;
@@ -1047,9 +1049,11 @@ void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
if (env->macsr & MACSR_V) {
env->macsr |= MACSR_PAV0 << acc;
if (env->macsr & MACSR_OMC) {
/* The result is saturated to 32 bits, despite overflow occurring
at 48 bits. Seems weird, but that's what the hardware docs
say. */
/*
* The result is saturated to 32 bits, despite overflow occurring
* at 48 bits. Seems weird, but that's what the hardware docs
* say.
*/
result = (result >> 63) ^ 0x7fffffff;
}
}
+16 -8
View File
@@ -130,7 +130,8 @@ static void m68k_semi_return_u32(CPUM68KState *env, uint32_t ret, uint32_t err)
target_ulong args = env->dregs[1];
if (put_user_u32(ret, args) ||
put_user_u32(err, args + 4)) {
/* The m68k semihosting ABI does not provide any way to report this
/*
* The m68k semihosting ABI does not provide any way to report this
* error to the guest, so the best we can do is log it in qemu.
* It is always a guest error not to pass us a valid argument block.
*/
@@ -159,8 +160,10 @@ static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
CPUM68KState *env = &cpu->env;
if (m68k_semi_is_fseek) {
/* FIXME: We've already lost the high bits of the fseek
return value. */
/*
* FIXME: We've already lost the high bits of the fseek
* return value.
*/
m68k_semi_return_u64(env, ret, err);
m68k_semi_is_fseek = 0;
} else {
@@ -168,7 +171,8 @@ static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
}
}
/* Read the input value from the argument block; fail the semihosting
/*
* Read the input value from the argument block; fail the semihosting
* call if the memory read fails.
*/
#define GET_ARG(n) do { \
@@ -440,14 +444,18 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
}
ts->heap_limit = base + size;
}
/* This call may happen before we have writable memory, so return
values directly in registers. */
/*
* This call may happen before we have writable memory, so return
* values directly in registers.
*/
env->dregs[1] = ts->heap_limit;
env->aregs[7] = ts->stack_base;
}
#else
/* FIXME: This is wrong for boards where RAM does not start at
address zero. */
/*
* FIXME: This is wrong for boards where RAM does not start at
* address zero.
*/
env->dregs[1] = ram_size;
env->aregs[7] = ram_size;
#endif
+37 -21
View File
@@ -494,10 +494,12 @@ bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
if (interrupt_request & CPU_INTERRUPT_HARD
&& ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) {
/* Real hardware gets the interrupt vector via an IACK cycle
at this point. Current emulated hardware doesn't rely on
this, so we provide/save the vector when the interrupt is
first signalled. */
/*
* Real hardware gets the interrupt vector via an IACK cycle
* at this point. Current emulated hardware doesn't rely on
* this, so we provide/save the vector when the interrupt is
* first signalled.
*/
cs->exception_index = env->pending_vector;
do_interrupt_m68k_hardirq(env);
return true;
@@ -537,7 +539,8 @@ void HELPER(divuw)(CPUM68KState *env, int destr, uint32_t den)
env->cc_c = 0; /* always cleared, even if overflow */
if (quot > 0xffff) {
env->cc_v = -1;
/* real 68040 keeps N and unset Z on overflow,
/*
* real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
@@ -564,7 +567,8 @@ void HELPER(divsw)(CPUM68KState *env, int destr, int32_t den)
if (quot != (int16_t)quot) {
env->cc_v = -1;
/* nothing else is modified */
/* real 68040 keeps N and unset Z on overflow,
/*
* real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
@@ -647,7 +651,8 @@ void HELPER(divull)(CPUM68KState *env, int numr, int regr, uint32_t den)
env->cc_c = 0; /* always cleared, even if overflow */
if (quot > 0xffffffffULL) {
env->cc_v = -1;
/* real 68040 keeps N and unset Z on overflow,
/*
* real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
@@ -681,7 +686,8 @@ void HELPER(divsll)(CPUM68KState *env, int numr, int regr, int32_t den)
env->cc_c = 0; /* always cleared, even if overflow */
if (quot != (int32_t)quot) {
env->cc_v = -1;
/* real 68040 keeps N and unset Z on overflow,
/*
* real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
@@ -838,14 +844,18 @@ static struct bf_data bf_prep(uint32_t addr, int32_t ofs, uint32_t len)
addr -= 1;
}
/* Compute the number of bytes required (minus one) to
satisfy the bitfield. */
/*
* Compute the number of bytes required (minus one) to
* satisfy the bitfield.
*/
blen = (bofs + len - 1) / 8;
/* Canonicalize the bit offset for data loaded into a 64-bit big-endian
word. For the cases where BLEN is not a power of 2, adjust ADDR so
that we can use the next power of two sized load without crossing a
page boundary, unless the field itself crosses the boundary. */
/*
* Canonicalize the bit offset for data loaded into a 64-bit big-endian
* word. For the cases where BLEN is not a power of 2, adjust ADDR so
* that we can use the next power of two sized load without crossing a
* page boundary, unless the field itself crosses the boundary.
*/
switch (blen) {
case 0:
bofs += 56;
@@ -937,8 +947,10 @@ uint64_t HELPER(bfextu_mem)(CPUM68KState *env, uint32_t addr,
struct bf_data d = bf_prep(addr, ofs, len);
uint64_t data = bf_load(env, d.addr, d.blen, ra);
/* Put CC_N at the top of the high word; put the zero-extended value
at the bottom of the low word. */
/*
* Put CC_N at the top of the high word; put the zero-extended value
* at the bottom of the low word.
*/
data <<= d.bofs;
data >>= 64 - d.len;
data |= data << (64 - d.len);
@@ -1016,15 +1028,18 @@ uint64_t HELPER(bfffo_mem)(CPUM68KState *env, uint32_t addr,
uint64_t n = (data & mask) << d.bofs;
uint32_t ffo = helper_bfffo_reg(n >> 32, ofs, d.len);
/* Return FFO in the low word and N in the high word.
Note that because of MASK and the shift, the low word
is already zero. */
/*
* Return FFO in the low word and N in the high word.
* Note that because of MASK and the shift, the low word
* is already zero.
*/
return n | ffo;
}
void HELPER(chk)(CPUM68KState *env, int32_t val, int32_t ub)
{
/* From the specs:
/*
* From the specs:
* X: Not affected, C,V,Z: Undefined,
* N: Set if val < 0; cleared if val > ub, undefined otherwise
* We implement here values found from a real MC68040:
@@ -1054,7 +1069,8 @@ void HELPER(chk)(CPUM68KState *env, int32_t val, int32_t ub)
void HELPER(chk2)(CPUM68KState *env, int32_t val, int32_t lb, int32_t ub)
{
/* From the specs:
/*
* From the specs:
* X: Not affected, N,V: Undefined,
* Z: Set if val is equal to lb or ub
* C: Set if val < lb or val > ub, cleared otherwise
+94 -87
View File
@@ -14,7 +14,8 @@
* the Softfloat-2a license unless specifically indicated otherwise.
*/
/* Portions of this work are licensed under the terms of the GNU GPL,
/*
* Portions of this work are licensed under the terms of the GNU GPL,
* version 2 or later. See the COPYING file in the top-level directory.
*/
@@ -41,10 +42,10 @@ static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
return a;
}
/*----------------------------------------------------------------------------
| Returns the modulo remainder of the extended double-precision floating-point
| value `a' with respect to the corresponding value `b'.
*----------------------------------------------------------------------------*/
/*
* Returns the modulo remainder of the extended double-precision floating-point
* value `a' with respect to the corresponding value `b'.
*/
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
{
@@ -124,10 +125,10 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
80, zSign, bExp + expDiff, aSig0, aSig1, status);
}
/*----------------------------------------------------------------------------
| Returns the mantissa of the extended double-precision floating-point
| value `a'.
*----------------------------------------------------------------------------*/
/*
* Returns the mantissa of the extended double-precision floating-point
* value `a'.
*/
floatx80 floatx80_getman(floatx80 a, float_status *status)
{
@@ -158,10 +159,10 @@ floatx80 floatx80_getman(floatx80 a, float_status *status)
0x3FFF, aSig, 0, status);
}
/*----------------------------------------------------------------------------
| Returns the exponent of the extended double-precision floating-point
| value `a' as an extended double-precision value.
*----------------------------------------------------------------------------*/
/*
* Returns the exponent of the extended double-precision floating-point
* value `a' as an extended double-precision value.
*/
floatx80 floatx80_getexp(floatx80 a, float_status *status)
{
@@ -191,13 +192,13 @@ floatx80 floatx80_getexp(floatx80 a, float_status *status)
return int32_to_floatx80(aExp - 0x3FFF, status);
}
/*----------------------------------------------------------------------------
| Scales extended double-precision floating-point value in operand `a' by
| value `b'. The function truncates the value in the second operand 'b' to
| an integral value and adds that value to the exponent of the operand 'a'.
| The operation performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
/*
* Scales extended double-precision floating-point value in operand `a' by
* value `b'. The function truncates the value in the second operand 'b' to
* an integral value and adds that value to the exponent of the operand 'a'.
* The operation performed according to the IEC/IEEE Standard for Binary
* Floating-Point Arithmetic.
*/
floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
{
@@ -282,26 +283,26 @@ floatx80 floatx80_move(floatx80 a, float_status *status)
aExp, aSig, 0, status);
}
/*----------------------------------------------------------------------------
| Algorithms for transcendental functions supported by MC68881 and MC68882
| mathematical coprocessors. The functions are derived from FPSP library.
*----------------------------------------------------------------------------*/
/*
* Algorithms for transcendental functions supported by MC68881 and MC68882
* mathematical coprocessors. The functions are derived from FPSP library.
*/
#define one_exp 0x3FFF
#define one_sig LIT64(0x8000000000000000)
/*----------------------------------------------------------------------------
| Function for compactifying extended double-precision floating point values.
*----------------------------------------------------------------------------*/
/*
* Function for compactifying extended double-precision floating point values.
*/
static int32_t floatx80_make_compact(int32_t aExp, uint64_t aSig)
{
return (aExp << 16) | (aSig >> 48);
}
/*----------------------------------------------------------------------------
| Log base e of x plus 1
*----------------------------------------------------------------------------*/
/*
* Log base e of x plus 1
*/
floatx80 floatx80_lognp1(floatx80 a, float_status *status)
{
@@ -498,9 +499,9 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Log base e
*----------------------------------------------------------------------------*/
/*
* Log base e
*/
floatx80 floatx80_logn(floatx80 a, float_status *status)
{
@@ -666,9 +667,9 @@ floatx80 floatx80_logn(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Log base 10
*----------------------------------------------------------------------------*/
/*
* Log base 10
*/
floatx80 floatx80_log10(floatx80 a, float_status *status)
{
@@ -723,9 +724,9 @@ floatx80 floatx80_log10(floatx80 a, float_status *status)
return a;
}
/*----------------------------------------------------------------------------
| Log base 2
*----------------------------------------------------------------------------*/
/*
* Log base 2
*/
floatx80 floatx80_log2(floatx80 a, float_status *status)
{
@@ -790,9 +791,9 @@ floatx80 floatx80_log2(floatx80 a, float_status *status)
return a;
}
/*----------------------------------------------------------------------------
| e to x
*----------------------------------------------------------------------------*/
/*
* e to x
*/
floatx80 floatx80_etox(floatx80 a, float_status *status)
{
@@ -848,7 +849,8 @@ floatx80 floatx80_etox(floatx80 a, float_status *status)
j = n & 0x3F; /* J = N mod 64 */
m = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
/* arithmetic right shift is division and
/*
* arithmetic right shift is division and
* round towards minus infinity
*/
m--;
@@ -973,9 +975,9 @@ floatx80 floatx80_etox(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| 2 to x
*----------------------------------------------------------------------------*/
/*
* 2 to x
*/
floatx80 floatx80_twotox(floatx80 a, float_status *status)
{
@@ -1051,14 +1053,16 @@ floatx80 floatx80_twotox(floatx80 a, float_status *status)
j = n & 0x3F;
l = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
/* arithmetic right shift is division and
/*
* arithmetic right shift is division and
* round towards minus infinity
*/
l--;
}
m = l / 2; /* NOTE: this is really arithmetic right shift by 1 */
if (l < 0 && (l & 1)) {
/* arithmetic right shift is division and
/*
* arithmetic right shift is division and
* round towards minus infinity
*/
m--;
@@ -1121,9 +1125,9 @@ floatx80 floatx80_twotox(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| 10 to x
*----------------------------------------------------------------------------*/
/*
* 10 to x
*/
floatx80 floatx80_tentox(floatx80 a, float_status *status)
{
@@ -1200,14 +1204,16 @@ floatx80 floatx80_tentox(floatx80 a, float_status *status)
j = n & 0x3F;
l = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
/* arithmetic right shift is division and
/*
* arithmetic right shift is division and
* round towards minus infinity
*/
l--;
}
m = l / 2; /* NOTE: this is really arithmetic right shift by 1 */
if (l < 0 && (l & 1)) {
/* arithmetic right shift is division and
/*
* arithmetic right shift is division and
* round towards minus infinity
*/
m--;
@@ -1274,9 +1280,9 @@ floatx80 floatx80_tentox(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Tangent
*----------------------------------------------------------------------------*/
/*
* Tangent
*/
floatx80 floatx80_tan(floatx80 a, float_status *status)
{
@@ -1484,9 +1490,9 @@ floatx80 floatx80_tan(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Sine
*----------------------------------------------------------------------------*/
/*
* Sine
*/
floatx80 floatx80_sin(floatx80 a, float_status *status)
{
@@ -1723,9 +1729,9 @@ floatx80 floatx80_sin(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Cosine
*----------------------------------------------------------------------------*/
/*
* Cosine
*/
floatx80 floatx80_cos(floatx80 a, float_status *status)
{
@@ -1960,9 +1966,9 @@ floatx80 floatx80_cos(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Arc tangent
*----------------------------------------------------------------------------*/
/*
* Arc tangent
*/
floatx80 floatx80_atan(floatx80 a, float_status *status)
{
@@ -2157,9 +2163,9 @@ floatx80 floatx80_atan(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Arc sine
*----------------------------------------------------------------------------*/
/*
* Arc sine
*/
floatx80 floatx80_asin(floatx80 a, float_status *status)
{
@@ -2222,9 +2228,9 @@ floatx80 floatx80_asin(floatx80 a, float_status *status)
return a;
}
/*----------------------------------------------------------------------------
| Arc cosine
*----------------------------------------------------------------------------*/
/*
* Arc cosine
*/
floatx80 floatx80_acos(floatx80 a, float_status *status)
{
@@ -2291,9 +2297,9 @@ floatx80 floatx80_acos(floatx80 a, float_status *status)
return a;
}
/*----------------------------------------------------------------------------
| Hyperbolic arc tangent
*----------------------------------------------------------------------------*/
/*
* Hyperbolic arc tangent
*/
floatx80 floatx80_atanh(floatx80 a, float_status *status)
{
@@ -2356,9 +2362,9 @@ floatx80 floatx80_atanh(floatx80 a, float_status *status)
return a;
}
/*----------------------------------------------------------------------------
| e to x minus 1
*----------------------------------------------------------------------------*/
/*
* e to x minus 1
*/
floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
{
@@ -2410,7 +2416,8 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
j = n & 0x3F; /* J = N mod 64 */
m = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
/* arithmetic right shift is division and
/*
* arithmetic right shift is division and
* round towards minus infinity
*/
m--;
@@ -2607,9 +2614,9 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Hyperbolic tangent
*----------------------------------------------------------------------------*/
/*
* Hyperbolic tangent
*/
floatx80 floatx80_tanh(floatx80 a, float_status *status)
{
@@ -2722,9 +2729,9 @@ floatx80 floatx80_tanh(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Hyperbolic sine
*----------------------------------------------------------------------------*/
/*
* Hyperbolic sine
*/
floatx80 floatx80_sinh(floatx80 a, float_status *status)
{
@@ -2811,9 +2818,9 @@ floatx80 floatx80_sinh(floatx80 a, float_status *status)
}
}
/*----------------------------------------------------------------------------
| Hyperbolic cosine
*----------------------------------------------------------------------------*/
/*
* Hyperbolic cosine
*/
floatx80 floatx80_cosh(floatx80 a, float_status *status)
{
+2 -1
View File
@@ -14,7 +14,8 @@
* the Softfloat-2a license unless specifically indicated otherwise.
*/
/* Portions of this work are licensed under the terms of the GNU GPL,
/*
* Portions of this work are licensed under the terms of the GNU GPL,
* version 2 or later. See the COPYING file in the top-level directory.
*/
+2 -1
View File
@@ -14,7 +14,8 @@
* the Softfloat-2a license unless specifically indicated otherwise.
*/
/* Portions of this work are licensed under the terms of the GNU GPL,
/*
* Portions of this work are licensed under the terms of the GNU GPL,
* version 2 or later. See the COPYING file in the top-level directory.
*/
+161 -85
View File
File diff suppressed because it is too large Load Diff