Commit 8384dd67fec5652a09ada4576214abfafab32c0c
1 parent
a8c768c0
Implement byte swapping accesses
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4574 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
104 additions
and
36 deletions
cpu-all.h
| @@ -233,6 +233,15 @@ static inline int lduw_le_p(void *ptr) | @@ -233,6 +233,15 @@ static inline int lduw_le_p(void *ptr) | ||
| 233 | int val; | 233 | int val; |
| 234 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | 234 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); |
| 235 | return val; | 235 | return val; |
| 236 | +#elif defined(__sparc__) | ||
| 237 | +#ifndef ASI_PRIMARY_LITTLE | ||
| 238 | +#define ASI_PRIMARY_LITTLE 0x88 | ||
| 239 | +#endif | ||
| 240 | + | ||
| 241 | + int val; | ||
| 242 | + __asm__ __volatile__ ("lduha [%1] %2, %0" : "=r" (val) : "r" (ptr), | ||
| 243 | + "i" (ASI_PRIMARY_LITTLE)); | ||
| 244 | + return val; | ||
| 236 | #else | 245 | #else |
| 237 | uint8_t *p = ptr; | 246 | uint8_t *p = ptr; |
| 238 | return p[0] | (p[1] << 8); | 247 | return p[0] | (p[1] << 8); |
| @@ -245,6 +254,11 @@ static inline int ldsw_le_p(void *ptr) | @@ -245,6 +254,11 @@ static inline int ldsw_le_p(void *ptr) | ||
| 245 | int val; | 254 | int val; |
| 246 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | 255 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); |
| 247 | return (int16_t)val; | 256 | return (int16_t)val; |
| 257 | +#elif defined(__sparc__) | ||
| 258 | + int val; | ||
| 259 | + __asm__ __volatile__ ("ldsha [%1] %2, %0" : "=r" (val) : "r" (ptr), | ||
| 260 | + "i" (ASI_PRIMARY_LITTLE)); | ||
| 261 | + return val; | ||
| 248 | #else | 262 | #else |
| 249 | uint8_t *p = ptr; | 263 | uint8_t *p = ptr; |
| 250 | return (int16_t)(p[0] | (p[1] << 8)); | 264 | return (int16_t)(p[0] | (p[1] << 8)); |
| @@ -257,6 +271,11 @@ static inline int ldl_le_p(void *ptr) | @@ -257,6 +271,11 @@ static inline int ldl_le_p(void *ptr) | ||
| 257 | int val; | 271 | int val; |
| 258 | __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | 272 | __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); |
| 259 | return val; | 273 | return val; |
| 274 | +#elif defined(__sparc__) | ||
| 275 | + int val; | ||
| 276 | + __asm__ __volatile__ ("lduwa [%1] %2, %0" : "=r" (val) : "r" (ptr), | ||
| 277 | + "i" (ASI_PRIMARY_LITTLE)); | ||
| 278 | + return val; | ||
| 260 | #else | 279 | #else |
| 261 | uint8_t *p = ptr; | 280 | uint8_t *p = ptr; |
| 262 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | 281 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
| @@ -265,17 +284,27 @@ static inline int ldl_le_p(void *ptr) | @@ -265,17 +284,27 @@ static inline int ldl_le_p(void *ptr) | ||
| 265 | 284 | ||
| 266 | static inline uint64_t ldq_le_p(void *ptr) | 285 | static inline uint64_t ldq_le_p(void *ptr) |
| 267 | { | 286 | { |
| 287 | +#if defined(__sparc__) | ||
| 288 | + uint64_t val; | ||
| 289 | + __asm__ __volatile__ ("ldxa [%1] %2, %0" : "=r" (val) : "r" (ptr), | ||
| 290 | + "i" (ASI_PRIMARY_LITTLE)); | ||
| 291 | + return val; | ||
| 292 | +#else | ||
| 268 | uint8_t *p = ptr; | 293 | uint8_t *p = ptr; |
| 269 | uint32_t v1, v2; | 294 | uint32_t v1, v2; |
| 270 | v1 = ldl_le_p(p); | 295 | v1 = ldl_le_p(p); |
| 271 | v2 = ldl_le_p(p + 4); | 296 | v2 = ldl_le_p(p + 4); |
| 272 | return v1 | ((uint64_t)v2 << 32); | 297 | return v1 | ((uint64_t)v2 << 32); |
| 298 | +#endif | ||
| 273 | } | 299 | } |
| 274 | 300 | ||
| 275 | static inline void stw_le_p(void *ptr, int v) | 301 | static inline void stw_le_p(void *ptr, int v) |
| 276 | { | 302 | { |
| 277 | #ifdef __powerpc__ | 303 | #ifdef __powerpc__ |
| 278 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); | 304 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); |
| 305 | +#elif defined(__sparc__) | ||
| 306 | + __asm__ __volatile__ ("stha %1, [%2] %3" : "=m" (*(uint16_t *)ptr) : "r" (v), | ||
| 307 | + "r" (ptr), "i" (ASI_PRIMARY_LITTLE)); | ||
| 279 | #else | 308 | #else |
| 280 | uint8_t *p = ptr; | 309 | uint8_t *p = ptr; |
| 281 | p[0] = v; | 310 | p[0] = v; |
| @@ -287,6 +316,9 @@ static inline void stl_le_p(void *ptr, int v) | @@ -287,6 +316,9 @@ static inline void stl_le_p(void *ptr, int v) | ||
| 287 | { | 316 | { |
| 288 | #ifdef __powerpc__ | 317 | #ifdef __powerpc__ |
| 289 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); | 318 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); |
| 319 | +#elif defined(__sparc__) | ||
| 320 | + __asm__ __volatile__ ("stwa %1, [%2] %3" : "=m" (*(uint32_t *)ptr) : "r" (v), | ||
| 321 | + "r" (ptr), "i" (ASI_PRIMARY_LITTLE)); | ||
| 290 | #else | 322 | #else |
| 291 | uint8_t *p = ptr; | 323 | uint8_t *p = ptr; |
| 292 | p[0] = v; | 324 | p[0] = v; |
| @@ -298,9 +330,15 @@ static inline void stl_le_p(void *ptr, int v) | @@ -298,9 +330,15 @@ static inline void stl_le_p(void *ptr, int v) | ||
| 298 | 330 | ||
| 299 | static inline void stq_le_p(void *ptr, uint64_t v) | 331 | static inline void stq_le_p(void *ptr, uint64_t v) |
| 300 | { | 332 | { |
| 333 | +#if defined(__sparc__) | ||
| 334 | + __asm__ __volatile__ ("stxa %1, [%2] %3" : "=m" (*(uint64_t *)ptr) : "r" (v), | ||
| 335 | + "r" (ptr), "i" (ASI_PRIMARY_LITTLE)); | ||
| 336 | +#undef ASI_PRIMARY_LITTLE | ||
| 337 | +#else | ||
| 301 | uint8_t *p = ptr; | 338 | uint8_t *p = ptr; |
| 302 | stl_le_p(p, (uint32_t)v); | 339 | stl_le_p(p, (uint32_t)v); |
| 303 | stl_le_p(p + 4, v >> 32); | 340 | stl_le_p(p + 4, v >> 32); |
| 341 | +#endif | ||
| 304 | } | 342 | } |
| 305 | 343 | ||
| 306 | /* float access */ | 344 | /* float access */ |
tcg/sparc/tcg-target.c
| @@ -178,6 +178,7 @@ static inline int tcg_target_const_match(tcg_target_long val, | @@ -178,6 +178,7 @@ static inline int tcg_target_const_match(tcg_target_long val, | ||
| 178 | #define INSN_RD(x) ((x) << 25) | 178 | #define INSN_RD(x) ((x) << 25) |
| 179 | #define INSN_RS1(x) ((x) << 14) | 179 | #define INSN_RS1(x) ((x) << 14) |
| 180 | #define INSN_RS2(x) (x) | 180 | #define INSN_RS2(x) (x) |
| 181 | +#define INSN_ASI(x) ((x) << 5) | ||
| 181 | 182 | ||
| 182 | #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) | 183 | #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) |
| 183 | #define INSN_OFF22(x) (((x) >> 2) & 0x3fffff) | 184 | #define INSN_OFF22(x) (((x) >> 2) & 0x3fffff) |
| @@ -242,6 +243,21 @@ static inline int tcg_target_const_match(tcg_target_long val, | @@ -242,6 +243,21 @@ static inline int tcg_target_const_match(tcg_target_long val, | ||
| 242 | #define STH (INSN_OP(3) | INSN_OP3(0x06)) | 243 | #define STH (INSN_OP(3) | INSN_OP3(0x06)) |
| 243 | #define STW (INSN_OP(3) | INSN_OP3(0x04)) | 244 | #define STW (INSN_OP(3) | INSN_OP3(0x04)) |
| 244 | #define STX (INSN_OP(3) | INSN_OP3(0x0e)) | 245 | #define STX (INSN_OP(3) | INSN_OP3(0x0e)) |
| 246 | +#define LDUBA (INSN_OP(3) | INSN_OP3(0x11)) | ||
| 247 | +#define LDSBA (INSN_OP(3) | INSN_OP3(0x19)) | ||
| 248 | +#define LDUHA (INSN_OP(3) | INSN_OP3(0x12)) | ||
| 249 | +#define LDSHA (INSN_OP(3) | INSN_OP3(0x1a)) | ||
| 250 | +#define LDUWA (INSN_OP(3) | INSN_OP3(0x10)) | ||
| 251 | +#define LDSWA (INSN_OP(3) | INSN_OP3(0x18)) | ||
| 252 | +#define LDXA (INSN_OP(3) | INSN_OP3(0x1b)) | ||
| 253 | +#define STBA (INSN_OP(3) | INSN_OP3(0x15)) | ||
| 254 | +#define STHA (INSN_OP(3) | INSN_OP3(0x16)) | ||
| 255 | +#define STWA (INSN_OP(3) | INSN_OP3(0x14)) | ||
| 256 | +#define STXA (INSN_OP(3) | INSN_OP3(0x1e)) | ||
| 257 | + | ||
| 258 | +#ifndef ASI_PRIMARY_LITTLE | ||
| 259 | +#define ASI_PRIMARY_LITTLE 0x88 | ||
| 260 | +#endif | ||
| 245 | 261 | ||
| 246 | static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2, | 262 | static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2, |
| 247 | int op) | 263 | int op) |
| @@ -332,6 +348,14 @@ static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, in | @@ -332,6 +348,14 @@ static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, in | ||
| 332 | } | 348 | } |
| 333 | } | 349 | } |
| 334 | 350 | ||
| 351 | +static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr, | ||
| 352 | + int offset, int op, int asi) | ||
| 353 | +{ | ||
| 354 | + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset); | ||
| 355 | + tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) | | ||
| 356 | + INSN_ASI(asi) | INSN_RS2(addr)); | ||
| 357 | +} | ||
| 358 | + | ||
| 335 | static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, | 359 | static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, |
| 336 | int arg1, tcg_target_long arg2) | 360 | int arg1, tcg_target_long arg2) |
| 337 | { | 361 | { |
| @@ -457,7 +481,7 @@ static const void * const qemu_st_helpers[4] = { | @@ -457,7 +481,7 @@ static const void * const qemu_st_helpers[4] = { | ||
| 457 | static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | 481 | static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, |
| 458 | int opc) | 482 | int opc) |
| 459 | { | 483 | { |
| 460 | - int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, ld_op; | 484 | + int addr_reg, data_reg, r0, r1, mem_index, s_bits, ld_op; |
| 461 | #if defined(CONFIG_SOFTMMU) | 485 | #if defined(CONFIG_SOFTMMU) |
| 462 | uint8_t *label1_ptr, *label2_ptr; | 486 | uint8_t *label1_ptr, *label2_ptr; |
| 463 | #endif | 487 | #endif |
| @@ -565,11 +589,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | @@ -565,11 +589,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | ||
| 565 | r0 = addr_reg; | 589 | r0 = addr_reg; |
| 566 | #endif | 590 | #endif |
| 567 | 591 | ||
| 568 | -#ifdef TARGET_WORDS_BIGENDIAN | ||
| 569 | - bswap = 0; | ||
| 570 | -#else | ||
| 571 | - bswap = 1; | ||
| 572 | -#endif | ||
| 573 | switch(opc) { | 592 | switch(opc) { |
| 574 | case 0: | 593 | case 0: |
| 575 | /* ldub [r0], data_reg */ | 594 | /* ldub [r0], data_reg */ |
| @@ -580,39 +599,49 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | @@ -580,39 +599,49 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | ||
| 580 | tcg_out_ldst(s, data_reg, r0, 0, LDSB); | 599 | tcg_out_ldst(s, data_reg, r0, 0, LDSB); |
| 581 | break; | 600 | break; |
| 582 | case 1: | 601 | case 1: |
| 602 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 583 | /* lduh [r0], data_reg */ | 603 | /* lduh [r0], data_reg */ |
| 584 | tcg_out_ldst(s, data_reg, r0, 0, LDUH); | 604 | tcg_out_ldst(s, data_reg, r0, 0, LDUH); |
| 585 | - if (bswap) { | ||
| 586 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 587 | - } | 605 | +#else |
| 606 | + /* lduha [r0] ASI_PRIMARY_LITTLE, data_reg */ | ||
| 607 | + tcg_out_ldst_asi(s, data_reg, r0, 0, LDUHA, ASI_PRIMARY_LITTLE); | ||
| 608 | +#endif | ||
| 588 | break; | 609 | break; |
| 589 | case 1 | 4: | 610 | case 1 | 4: |
| 611 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 590 | /* ldsh [r0], data_reg */ | 612 | /* ldsh [r0], data_reg */ |
| 591 | tcg_out_ldst(s, data_reg, r0, 0, LDSH); | 613 | tcg_out_ldst(s, data_reg, r0, 0, LDSH); |
| 592 | - if (bswap) { | ||
| 593 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 594 | - } | 614 | +#else |
| 615 | + /* ldsha [r0] ASI_PRIMARY_LITTLE, data_reg */ | ||
| 616 | + tcg_out_ldst_asi(s, data_reg, r0, 0, LDSHA, ASI_PRIMARY_LITTLE); | ||
| 617 | +#endif | ||
| 595 | break; | 618 | break; |
| 596 | case 2: | 619 | case 2: |
| 620 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 597 | /* lduw [r0], data_reg */ | 621 | /* lduw [r0], data_reg */ |
| 598 | tcg_out_ldst(s, data_reg, r0, 0, LDUW); | 622 | tcg_out_ldst(s, data_reg, r0, 0, LDUW); |
| 599 | - if (bswap) { | ||
| 600 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 601 | - } | 623 | +#else |
| 624 | + /* lduwa [r0] ASI_PRIMARY_LITTLE, data_reg */ | ||
| 625 | + tcg_out_ldst_asi(s, data_reg, r0, 0, LDUWA, ASI_PRIMARY_LITTLE); | ||
| 626 | +#endif | ||
| 602 | break; | 627 | break; |
| 603 | case 2 | 4: | 628 | case 2 | 4: |
| 629 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 604 | /* ldsw [r0], data_reg */ | 630 | /* ldsw [r0], data_reg */ |
| 605 | tcg_out_ldst(s, data_reg, r0, 0, LDSW); | 631 | tcg_out_ldst(s, data_reg, r0, 0, LDSW); |
| 606 | - if (bswap) { | ||
| 607 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 608 | - } | 632 | +#else |
| 633 | + /* ldswa [r0] ASI_PRIMARY_LITTLE, data_reg */ | ||
| 634 | + tcg_out_ldst_asi(s, data_reg, r0, 0, LDSWA, ASI_PRIMARY_LITTLE); | ||
| 635 | +#endif | ||
| 609 | break; | 636 | break; |
| 610 | case 3: | 637 | case 3: |
| 638 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 611 | /* ldx [r0], data_reg */ | 639 | /* ldx [r0], data_reg */ |
| 612 | tcg_out_ldst(s, data_reg, r0, 0, LDX); | 640 | tcg_out_ldst(s, data_reg, r0, 0, LDX); |
| 613 | - if (bswap) { | ||
| 614 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 615 | - } | 641 | +#else |
| 642 | + /* ldxa [r0] ASI_PRIMARY_LITTLE, data_reg */ | ||
| 643 | + tcg_out_ldst_asi(s, data_reg, r0, 0, LDXA, ASI_PRIMARY_LITTLE); | ||
| 644 | +#endif | ||
| 616 | break; | 645 | break; |
| 617 | default: | 646 | default: |
| 618 | tcg_abort(); | 647 | tcg_abort(); |
| @@ -629,7 +658,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | @@ -629,7 +658,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | ||
| 629 | static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | 658 | static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, |
| 630 | int opc) | 659 | int opc) |
| 631 | { | 660 | { |
| 632 | - int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, ld_op; | 661 | + int addr_reg, data_reg, r0, r1, mem_index, s_bits, ld_op; |
| 633 | #if defined(CONFIG_SOFTMMU) | 662 | #if defined(CONFIG_SOFTMMU) |
| 634 | uint8_t *label1_ptr, *label2_ptr; | 663 | uint8_t *label1_ptr, *label2_ptr; |
| 635 | #endif | 664 | #endif |
| @@ -737,36 +766,37 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | @@ -737,36 +766,37 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | ||
| 737 | r0 = addr_reg; | 766 | r0 = addr_reg; |
| 738 | #endif | 767 | #endif |
| 739 | 768 | ||
| 740 | -#ifdef TARGET_WORDS_BIGENDIAN | ||
| 741 | - bswap = 0; | ||
| 742 | -#else | ||
| 743 | - bswap = 1; | ||
| 744 | -#endif | ||
| 745 | switch(opc) { | 769 | switch(opc) { |
| 746 | case 0: | 770 | case 0: |
| 747 | /* stb data_reg, [r0] */ | 771 | /* stb data_reg, [r0] */ |
| 748 | tcg_out_ldst(s, data_reg, r0, 0, STB); | 772 | tcg_out_ldst(s, data_reg, r0, 0, STB); |
| 749 | break; | 773 | break; |
| 750 | case 1: | 774 | case 1: |
| 751 | - if (bswap) { | ||
| 752 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 753 | - } | 775 | +#ifdef TARGET_WORDS_BIGENDIAN |
| 754 | /* sth data_reg, [r0] */ | 776 | /* sth data_reg, [r0] */ |
| 755 | tcg_out_ldst(s, data_reg, r0, 0, STH); | 777 | tcg_out_ldst(s, data_reg, r0, 0, STH); |
| 778 | +#else | ||
| 779 | + /* stha data_reg, [r0] ASI_PRIMARY_LITTLE */ | ||
| 780 | + tcg_out_ldst_asi(s, data_reg, r0, 0, STHA, ASI_PRIMARY_LITTLE); | ||
| 781 | +#endif | ||
| 756 | break; | 782 | break; |
| 757 | case 2: | 783 | case 2: |
| 758 | - if (bswap) { | ||
| 759 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 760 | - } | 784 | +#ifdef TARGET_WORDS_BIGENDIAN |
| 761 | /* stw data_reg, [r0] */ | 785 | /* stw data_reg, [r0] */ |
| 762 | tcg_out_ldst(s, data_reg, r0, 0, STW); | 786 | tcg_out_ldst(s, data_reg, r0, 0, STW); |
| 787 | +#else | ||
| 788 | + /* stwa data_reg, [r0] ASI_PRIMARY_LITTLE */ | ||
| 789 | + tcg_out_ldst_asi(s, data_reg, r0, 0, STWA, ASI_PRIMARY_LITTLE); | ||
| 790 | +#endif | ||
| 763 | break; | 791 | break; |
| 764 | case 3: | 792 | case 3: |
| 765 | - if (bswap) { | ||
| 766 | - fprintf(stderr, "unimplemented %s with bswap\n", __func__); | ||
| 767 | - } | 793 | +#ifdef TARGET_WORDS_BIGENDIAN |
| 768 | /* stx data_reg, [r0] */ | 794 | /* stx data_reg, [r0] */ |
| 769 | tcg_out_ldst(s, data_reg, r0, 0, STX); | 795 | tcg_out_ldst(s, data_reg, r0, 0, STX); |
| 796 | +#else | ||
| 797 | + /* stxa data_reg, [r0] ASI_PRIMARY_LITTLE */ | ||
| 798 | + tcg_out_ldst_asi(s, data_reg, r0, 0, STXA, ASI_PRIMARY_LITTLE); | ||
| 799 | +#endif | ||
| 770 | break; | 800 | break; |
| 771 | default: | 801 | default: |
| 772 | tcg_abort(); | 802 | tcg_abort(); |