op_helper.c 15.7 KB
Newer Older
B
bellard 已提交
1 2
/*
 *  SH4 emulation
3
 *
B
bellard 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16
 *  Copyright (c) 2005 Samuel Tardieu
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
B
bellard 已提交
18 19
 */
#include <assert.h>
E
edgar_igl 已提交
20
#include <stdlib.h>
B
bellard 已提交
21
#include "exec.h"
P
pbrook 已提交
22
#include "helper.h"
B
bellard 已提交
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
static void cpu_restore_state_from_retaddr(void *retaddr)
{
    TranslationBlock *tb;
    unsigned long pc;

    if (retaddr) {
        pc = (unsigned long) retaddr;
        tb = tb_find_pc(pc);
        if (tb) {
            /* the PC is inside the translated code. It means that we have
               a virtual CPU fault */
            cpu_restore_state(tb, env, pc, NULL);
        }
    }
}

B
bellard 已提交
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#ifndef CONFIG_USER_ONLY

#define MMUSUFFIX _mmu

#define SHIFT 0
#include "softmmu_template.h"

#define SHIFT 1
#include "softmmu_template.h"

#define SHIFT 2
#include "softmmu_template.h"

#define SHIFT 3
#include "softmmu_template.h"

56
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
B
bellard 已提交
57 58 59 60 61 62 63 64
{
    CPUState *saved_env;
    int ret;

    /* XXX: hack to restore env in all cases, even if not called from
       generated code */
    saved_env = env;
    env = cpu_single_env;
65
    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
B
bellard 已提交
66
    if (ret) {
67 68
        /* now we have a real cpu fault */
        cpu_restore_state_from_retaddr(retaddr);
A
aurel32 已提交
69
	cpu_loop_exit();
B
bellard 已提交
70 71 72 73 74 75
    }
    env = saved_env;
}

#endif

A
aurel32 已提交
76 77 78 79
void helper_ldtlb(void)
{
#ifdef CONFIG_USER_ONLY
    /* XXXXX */
80
    cpu_abort(env, "Unhandled ldtlb");
A
aurel32 已提交
81 82 83 84 85
#else
    cpu_load_tlb(env);
#endif
}

A
aurel32 已提交
86 87 88 89 90 91 92 93 94 95 96 97
void helper_raise_illegal_instruction(void)
{
    env->exception_index = 0x180;
    cpu_loop_exit();
}

void helper_raise_slot_illegal_instruction(void)
{
    env->exception_index = 0x1a0;
    cpu_loop_exit();
}

A
aurel32 已提交
98 99 100 101 102 103 104 105 106 107 108 109
void helper_raise_fpu_disable(void)
{
  env->exception_index = 0x800;
  cpu_loop_exit();
}

void helper_raise_slot_fpu_disable(void)
{
  env->exception_index = 0x820;
  cpu_loop_exit();
}

A
aurel32 已提交
110 111 112 113 114 115
void helper_debug(void)
{
    env->exception_index = EXCP_DEBUG;
    cpu_loop_exit();
}

A
aurel32 已提交
116
void helper_sleep(uint32_t next_pc)
A
aurel32 已提交
117 118 119
{
    env->halted = 1;
    env->exception_index = EXCP_HLT;
A
aurel32 已提交
120
    env->pc = next_pc;
A
aurel32 已提交
121 122 123 124 125 126 127 128 129 130
    cpu_loop_exit();
}

void helper_trapa(uint32_t tra)
{
    env->tra = tra << 2;
    env->exception_index = 0x160;
    cpu_loop_exit();
}

E
edgar_igl 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
void helper_movcal(uint32_t address, uint32_t value)
{
    if (cpu_sh4_is_cached (env, address))
    {
	memory_content *r = malloc (sizeof(memory_content));
	r->address = address;
	r->value = value;
	r->next = NULL;

	*(env->movcal_backup_tail) = r;
	env->movcal_backup_tail = &(r->next);
    }
}

void helper_discard_movcal_backup(void)
{
    memory_content *current = env->movcal_backup;

    while(current)
    {
	memory_content *next = current->next;
	free (current);
	env->movcal_backup = current = next;
154
	if (current == NULL)
E
edgar_igl 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
	    env->movcal_backup_tail = &(env->movcal_backup);
    } 
}

void helper_ocbi(uint32_t address)
{
    memory_content **current = &(env->movcal_backup);
    while (*current)
    {
	uint32_t a = (*current)->address;
	if ((a & ~0x1F) == (address & ~0x1F))
	{
	    memory_content *next = (*current)->next;
	    stl(a, (*current)->value);
	    
170
	    if (next == NULL)
E
edgar_igl 已提交
171 172 173 174 175 176 177 178 179 180 181
	    {
		env->movcal_backup_tail = current;
	    }

	    free (*current);
	    *current = next;
	    break;
	}
    }
}

182
uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
183 184 185
{
    uint32_t tmp0, tmp1;

186 187 188
    tmp1 = arg0 + arg1;
    tmp0 = arg1;
    arg1 = tmp1 + (env->sr & 1);
B
bellard 已提交
189 190 191 192
    if (tmp0 > tmp1)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
193
    if (tmp1 > arg1)
B
bellard 已提交
194
	env->sr |= SR_T;
195
    return arg1;
B
bellard 已提交
196 197
}

198
uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
199 200 201
{
    uint32_t dest, src, ans;

202
    if ((int32_t) arg1 >= 0)
B
bellard 已提交
203 204 205
	dest = 0;
    else
	dest = 1;
206
    if ((int32_t) arg0 >= 0)
B
bellard 已提交
207 208 209 210
	src = 0;
    else
	src = 1;
    src += dest;
211 212
    arg1 += arg0;
    if ((int32_t) arg1 >= 0)
B
bellard 已提交
213 214 215 216 217 218 219 220 221 222 223
	ans = 0;
    else
	ans = 1;
    ans += dest;
    if (src == 0 || src == 2) {
	if (ans == 1)
	    env->sr |= SR_T;
	else
	    env->sr &= ~SR_T;
    } else
	env->sr &= ~SR_T;
224
    return arg1;
B
bellard 已提交
225 226 227 228 229 230 231 232 233 234 235 236
}

#define T (env->sr & SR_T)
#define Q (env->sr & SR_Q ? 1 : 0)
#define M (env->sr & SR_M ? 1 : 0)
#define SETT env->sr |= SR_T
#define CLRT env->sr &= ~SR_T
#define SETQ env->sr |= SR_Q
#define CLRQ env->sr &= ~SR_Q
#define SETM env->sr |= SR_M
#define CLRM env->sr &= ~SR_M

237
uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
238 239 240 241
{
    uint32_t tmp0, tmp2;
    uint8_t old_q, tmp1 = 0xff;

242
    //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
B
bellard 已提交
243
    old_q = Q;
244
    if ((0x80000000 & arg1) != 0)
B
bellard 已提交
245 246 247
	SETQ;
    else
	CLRQ;
248 249 250
    tmp2 = arg0;
    arg1 <<= 1;
    arg1 |= T;
B
bellard 已提交
251 252 253 254
    switch (old_q) {
    case 0:
	switch (M) {
	case 0:
255 256 257
	    tmp0 = arg1;
	    arg1 -= tmp2;
	    tmp1 = arg1 > tmp0;
B
bellard 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
	    switch (Q) {
	    case 0:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	case 1:
274 275 276
	    tmp0 = arg1;
	    arg1 += tmp2;
	    tmp1 = arg1 < tmp0;
B
bellard 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
	    switch (Q) {
	    case 0:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	}
	break;
    case 1:
	switch (M) {
	case 0:
297 298 299
	    tmp0 = arg1;
	    arg1 += tmp2;
	    tmp1 = arg1 < tmp0;
B
bellard 已提交
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
	    switch (Q) {
	    case 0:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	case 1:
316 317 318
	    tmp0 = arg1;
	    arg1 -= tmp2;
	    tmp1 = arg1 > tmp0;
B
bellard 已提交
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
	    switch (Q) {
	    case 0:
		if (tmp1 == 0)
		    SETQ;
		else
		    CLRQ;
		break;
	    case 1:
		if (tmp1)
		    SETQ;
		else
		    CLRQ;
		break;
	    }
	    break;
	}
	break;
    }
    if (Q == M)
	SETT;
    else
	CLRT;
341 342
    //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
    return arg1;
B
bellard 已提交
343 344
}

345
void helper_macl(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
346 347 348 349
{
    int64_t res;

    res = ((uint64_t) env->mach << 32) | env->macl;
350
    res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
B
bellard 已提交
351 352 353 354 355 356 357 358 359 360
    env->mach = (res >> 32) & 0xffffffff;
    env->macl = res & 0xffffffff;
    if (env->sr & SR_S) {
	if (res < 0)
	    env->mach |= 0xffff0000;
	else
	    env->mach &= 0x00007fff;
    }
}

361
void helper_macw(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
362 363 364 365
{
    int64_t res;

    res = ((uint64_t) env->mach << 32) | env->macl;
366
    res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
B
bellard 已提交
367 368 369 370 371 372 373 374 375 376 377 378 379
    env->mach = (res >> 32) & 0xffffffff;
    env->macl = res & 0xffffffff;
    if (env->sr & SR_S) {
	if (res < -0x80000000) {
	    env->mach = 1;
	    env->macl = 0x80000000;
	} else if (res > 0x000000007fffffff) {
	    env->mach = 1;
	    env->macl = 0x7fffffff;
	}
    }
}

380
uint32_t helper_negc(uint32_t arg)
B
bellard 已提交
381 382 383
{
    uint32_t temp;

384 385
    temp = -arg;
    arg = temp - (env->sr & SR_T);
B
bellard 已提交
386 387 388 389
    if (0 < temp)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
390
    if (temp < arg)
B
bellard 已提交
391
	env->sr |= SR_T;
392
    return arg;
B
bellard 已提交
393 394
}

395
uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
396 397 398
{
    uint32_t tmp0, tmp1;

399 400 401
    tmp1 = arg1 - arg0;
    tmp0 = arg1;
    arg1 = tmp1 - (env->sr & SR_T);
B
bellard 已提交
402 403 404 405
    if (tmp0 < tmp1)
	env->sr |= SR_T;
    else
	env->sr &= ~SR_T;
406
    if (tmp1 < arg1)
B
bellard 已提交
407
	env->sr |= SR_T;
408
    return arg1;
B
bellard 已提交
409 410
}

411
uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
B
bellard 已提交
412 413 414
{
    int32_t dest, src, ans;

415
    if ((int32_t) arg1 >= 0)
B
bellard 已提交
416 417 418
	dest = 0;
    else
	dest = 1;
419
    if ((int32_t) arg0 >= 0)
B
bellard 已提交
420 421 422 423
	src = 0;
    else
	src = 1;
    src += dest;
424 425
    arg1 -= arg0;
    if ((int32_t) arg1 >= 0)
B
bellard 已提交
426 427 428 429 430 431 432 433 434 435 436
	ans = 0;
    else
	ans = 1;
    ans += dest;
    if (src == 1) {
	if (ans == 1)
	    env->sr |= SR_T;
	else
	    env->sr &= ~SR_T;
    } else
	env->sr &= ~SR_T;
437
    return arg1;
B
bellard 已提交
438 439
}

A
aurel32 已提交
440 441 442 443 444 445 446 447 448 449
static inline void set_t(void)
{
    env->sr |= SR_T;
}

static inline void clr_t(void)
{
    env->sr &= ~SR_T;
}

450 451
void helper_ld_fpscr(uint32_t val)
{
452 453
    env->fpscr = val & FPSCR_MASK;
    if ((val & FPSCR_RM_MASK) == FPSCR_RM_ZERO) {
454
	set_float_rounding_mode(float_round_to_zero, &env->fp_status);
455
    } else {
456
	set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
457
    }
458
    set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
459
}
A
aurel32 已提交
460

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
static void update_fpscr(void *retaddr)
{
    int xcpt, cause, enable;

    xcpt = get_float_exception_flags(&env->fp_status);

    /* Clear the flag entries */
    env->fpscr &= ~FPSCR_FLAG_MASK;

    if (unlikely(xcpt)) {
        if (xcpt & float_flag_invalid) {
            env->fpscr |= FPSCR_FLAG_V;
        }
        if (xcpt & float_flag_divbyzero) {
            env->fpscr |= FPSCR_FLAG_Z;
        }
        if (xcpt & float_flag_overflow) {
            env->fpscr |= FPSCR_FLAG_O;
        }
        if (xcpt & float_flag_underflow) {
            env->fpscr |= FPSCR_FLAG_U;
        }
        if (xcpt & float_flag_inexact) {
            env->fpscr |= FPSCR_FLAG_I;
        }

        /* Accumulate in cause entries */
        env->fpscr |= (env->fpscr & FPSCR_FLAG_MASK)
                      << (FPSCR_CAUSE_SHIFT - FPSCR_FLAG_SHIFT);

        /* Generate an exception if enabled */
        cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT;
        enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT;
        if (cause & enable) {
            cpu_restore_state_from_retaddr(retaddr);
            env->exception_index = 0x120;
            cpu_loop_exit();
        }
    }
}

A
aurel32 已提交
502 503
uint32_t helper_fabs_FT(uint32_t t0)
{
504 505 506 507
    CPU_FloatU f;
    f.l = t0;
    f.f = float32_abs(f.f);
    return f.l;
A
aurel32 已提交
508 509 510 511
}

uint64_t helper_fabs_DT(uint64_t t0)
{
512 513 514 515
    CPU_DoubleU d;
    d.ll = t0;
    d.d = float64_abs(d.d);
    return d.ll;
A
aurel32 已提交
516 517 518 519
}

uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1)
{
520 521 522
    CPU_FloatU f0, f1;
    f0.l = t0;
    f1.l = t1;
523
    set_float_exception_flags(0, &env->fp_status);
524
    f0.f = float32_add(f0.f, f1.f, &env->fp_status);
525
    update_fpscr(GETPC());
526
    return f0.l;
A
aurel32 已提交
527 528 529 530
}

uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1)
{
531 532 533
    CPU_DoubleU d0, d1;
    d0.ll = t0;
    d1.ll = t1;
534
    set_float_exception_flags(0, &env->fp_status);
535
    d0.d = float64_add(d0.d, d1.d, &env->fp_status);
536
    update_fpscr(GETPC());
537
    return d0.ll;
A
aurel32 已提交
538 539 540 541
}

void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
{
542
    CPU_FloatU f0, f1;
543
    int relation;
544 545 546
    f0.l = t0;
    f1.l = t1;

547 548 549 550 551
    set_float_exception_flags(0, &env->fp_status);
    relation = float32_compare(f0.f, f1.f, &env->fp_status);
    if (unlikely(relation == float_relation_unordered)) {
        update_fpscr(GETPC());
    } else if (relation == float_relation_equal) {
A
aurel32 已提交
552
	set_t();
553
    } else {
A
aurel32 已提交
554
	clr_t();
555
    }
A
aurel32 已提交
556 557 558 559
}

void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
{
560
    CPU_DoubleU d0, d1;
561
    int relation;
562 563 564
    d0.ll = t0;
    d1.ll = t1;

565 566 567 568 569
    set_float_exception_flags(0, &env->fp_status);
    relation = float64_compare(d0.d, d1.d, &env->fp_status);
    if (unlikely(relation == float_relation_unordered)) {
        update_fpscr(GETPC());
    } else if (relation == float_relation_equal) {
A
aurel32 已提交
570
	set_t();
571
    } else {
A
aurel32 已提交
572
	clr_t();
573
    }
A
aurel32 已提交
574 575 576 577
}

void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
{
578
    CPU_FloatU f0, f1;
579
    int relation;
580 581 582
    f0.l = t0;
    f1.l = t1;

583 584 585 586 587
    set_float_exception_flags(0, &env->fp_status);
    relation = float32_compare(f0.f, f1.f, &env->fp_status);
    if (unlikely(relation == float_relation_unordered)) {
        update_fpscr(GETPC());
    } else if (relation == float_relation_greater) {
A
aurel32 已提交
588
	set_t();
589
    } else {
A
aurel32 已提交
590
	clr_t();
591
    }
A
aurel32 已提交
592 593 594 595
}

void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
{
596
    CPU_DoubleU d0, d1;
597
    int relation;
598 599 600
    d0.ll = t0;
    d1.ll = t1;

601 602 603 604 605
    set_float_exception_flags(0, &env->fp_status);
    relation = float64_compare(d0.d, d1.d, &env->fp_status);
    if (unlikely(relation == float_relation_unordered)) {
        update_fpscr(GETPC());
    } else if (relation == float_relation_greater) {
A
aurel32 已提交
606
	set_t();
607
    } else {
A
aurel32 已提交
608
	clr_t();
609
    }
A
aurel32 已提交
610 611 612 613
}

uint64_t helper_fcnvsd_FT_DT(uint32_t t0)
{
614 615 616
    CPU_DoubleU d;
    CPU_FloatU f;
    f.l = t0;
617
    set_float_exception_flags(0, &env->fp_status);
618
    d.d = float32_to_float64(f.f, &env->fp_status);
619
    update_fpscr(GETPC());
620
    return d.ll;
A
aurel32 已提交
621 622 623 624
}

uint32_t helper_fcnvds_DT_FT(uint64_t t0)
{
625 626 627
    CPU_DoubleU d;
    CPU_FloatU f;
    d.ll = t0;
628
    set_float_exception_flags(0, &env->fp_status);
629
    f.f = float64_to_float32(d.d, &env->fp_status);
630
    update_fpscr(GETPC());
631
    return f.l;
A
aurel32 已提交
632 633 634 635
}

uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
{
636 637 638
    CPU_FloatU f0, f1;
    f0.l = t0;
    f1.l = t1;
639
    set_float_exception_flags(0, &env->fp_status);
640
    f0.f = float32_div(f0.f, f1.f, &env->fp_status);
641
    update_fpscr(GETPC());
642
    return f0.l;
A
aurel32 已提交
643 644 645 646
}

uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1)
{
647 648 649
    CPU_DoubleU d0, d1;
    d0.ll = t0;
    d1.ll = t1;
650
    set_float_exception_flags(0, &env->fp_status);
651
    d0.d = float64_div(d0.d, d1.d, &env->fp_status);
652
    update_fpscr(GETPC());
653
    return d0.ll;
A
aurel32 已提交
654 655 656 657
}

uint32_t helper_float_FT(uint32_t t0)
{
658
    CPU_FloatU f;
659 660

    set_float_exception_flags(0, &env->fp_status);
661
    f.f = int32_to_float32(t0, &env->fp_status);
662 663
    update_fpscr(GETPC());

664
    return f.l;
A
aurel32 已提交
665 666 667 668
}

uint64_t helper_float_DT(uint32_t t0)
{
669
    CPU_DoubleU d;
670
    set_float_exception_flags(0, &env->fp_status);
671
    d.d = int32_to_float64(t0, &env->fp_status);
672
    update_fpscr(GETPC());
673
    return d.ll;
A
aurel32 已提交
674 675
}

A
aurel32 已提交
676 677 678 679 680 681
uint32_t helper_fmac_FT(uint32_t t0, uint32_t t1, uint32_t t2)
{
    CPU_FloatU f0, f1, f2;
    f0.l = t0;
    f1.l = t1;
    f2.l = t2;
682
    set_float_exception_flags(0, &env->fp_status);
A
aurel32 已提交
683 684
    f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
    f0.f = float32_add(f0.f, f2.f, &env->fp_status);
685 686
    update_fpscr(GETPC());

A
aurel32 已提交
687 688 689
    return f0.l;
}

A
aurel32 已提交
690 691
uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1)
{
692 693 694
    CPU_FloatU f0, f1;
    f0.l = t0;
    f1.l = t1;
695
    set_float_exception_flags(0, &env->fp_status);
696
    f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
697
    update_fpscr(GETPC());
698
    return f0.l;
A
aurel32 已提交
699 700 701 702
}

uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1)
{
703 704 705
    CPU_DoubleU d0, d1;
    d0.ll = t0;
    d1.ll = t1;
706
    set_float_exception_flags(0, &env->fp_status);
707
    d0.d = float64_mul(d0.d, d1.d, &env->fp_status);
708 709
    update_fpscr(GETPC());

710
    return d0.ll;
A
aurel32 已提交
711 712
}

A
aurel32 已提交
713 714
uint32_t helper_fneg_T(uint32_t t0)
{
715 716 717 718
    CPU_FloatU f;
    f.l = t0;
    f.f = float32_chs(f.f);
    return f.l;
A
aurel32 已提交
719 720
}

A
aurel32 已提交
721 722
uint32_t helper_fsqrt_FT(uint32_t t0)
{
723 724
    CPU_FloatU f;
    f.l = t0;
725
    set_float_exception_flags(0, &env->fp_status);
726
    f.f = float32_sqrt(f.f, &env->fp_status);
727
    update_fpscr(GETPC());
728
    return f.l;
A
aurel32 已提交
729 730 731 732
}

uint64_t helper_fsqrt_DT(uint64_t t0)
{
733 734
    CPU_DoubleU d;
    d.ll = t0;
735
    set_float_exception_flags(0, &env->fp_status);
736
    d.d = float64_sqrt(d.d, &env->fp_status);
737
    update_fpscr(GETPC());
738
    return d.ll;
A
aurel32 已提交
739 740 741 742
}

uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1)
{
743 744 745
    CPU_FloatU f0, f1;
    f0.l = t0;
    f1.l = t1;
746
    set_float_exception_flags(0, &env->fp_status);
747
    f0.f = float32_sub(f0.f, f1.f, &env->fp_status);
748
    update_fpscr(GETPC());
749
    return f0.l;
A
aurel32 已提交
750 751 752 753
}

uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1)
{
754
    CPU_DoubleU d0, d1;
755

756 757
    d0.ll = t0;
    d1.ll = t1;
758
    set_float_exception_flags(0, &env->fp_status);
759
    d0.d = float64_sub(d0.d, d1.d, &env->fp_status);
760
    update_fpscr(GETPC());
761
    return d0.ll;
A
aurel32 已提交
762 763 764 765
}

uint32_t helper_ftrc_FT(uint32_t t0)
{
766
    CPU_FloatU f;
767
    uint32_t ret;
768
    f.l = t0;
769 770 771 772
    set_float_exception_flags(0, &env->fp_status);
    ret = float32_to_int32_round_to_zero(f.f, &env->fp_status);
    update_fpscr(GETPC());
    return ret;
A
aurel32 已提交
773 774 775 776
}

uint32_t helper_ftrc_DT(uint64_t t0)
{
777
    CPU_DoubleU d;
778
    uint32_t ret;
779
    d.ll = t0;
780 781 782 783
    set_float_exception_flags(0, &env->fp_status);
    ret = float64_to_int32_round_to_zero(d.d, &env->fp_status);
    update_fpscr(GETPC());
    return ret;
A
aurel32 已提交
784
}