translate.c (27a03171d02ee0de8de4e2d3bed241795d672859) translate.c (08149118839735f8559e63a69ec41434d919e11b)
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public

--- 5165 unchanged lines hidden (view full) ---

5174 if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
5175 (xop > 0x17 && xop <= 0x1d ) ||
5176 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
5177 TCGv cpu_val = gen_dest_gpr(dc, rd);
5178
5179 switch (xop) {
5180 case 0x0: /* ld, V9 lduw, load unsigned word */
5181 gen_address_mask(dc, cpu_addr);
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public

--- 5165 unchanged lines hidden (view full) ---

5174 if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
5175 (xop > 0x17 && xop <= 0x1d ) ||
5176 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
5177 TCGv cpu_val = gen_dest_gpr(dc, rd);
5178
5179 switch (xop) {
5180 case 0x0: /* ld, V9 lduw, load unsigned word */
5181 gen_address_mask(dc, cpu_addr);
5182 tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
5182 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
5183 dc->mem_idx, MO_TEUL);
5183 break;
5184 case 0x1: /* ldub, load unsigned byte */
5185 gen_address_mask(dc, cpu_addr);
5184 break;
5185 case 0x1: /* ldub, load unsigned byte */
5186 gen_address_mask(dc, cpu_addr);
5186 tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
5187 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
5188 dc->mem_idx, MO_UB);
5187 break;
5188 case 0x2: /* lduh, load unsigned halfword */
5189 gen_address_mask(dc, cpu_addr);
5189 break;
5190 case 0x2: /* lduh, load unsigned halfword */
5191 gen_address_mask(dc, cpu_addr);
5190 tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
5192 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
5193 dc->mem_idx, MO_TEUW);
5191 break;
5192 case 0x3: /* ldd, load double word */
5193 if (rd & 1)
5194 goto illegal_insn;
5195 else {
5196 TCGv_i64 t64;
5197
5198 gen_address_mask(dc, cpu_addr);
5199 t64 = tcg_temp_new_i64();
5194 break;
5195 case 0x3: /* ldd, load double word */
5196 if (rd & 1)
5197 goto illegal_insn;
5198 else {
5199 TCGv_i64 t64;
5200
5201 gen_address_mask(dc, cpu_addr);
5202 t64 = tcg_temp_new_i64();
5200 tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
5203 tcg_gen_qemu_ld_i64(t64, cpu_addr,
5204 dc->mem_idx, MO_TEUQ);
5201 tcg_gen_trunc_i64_tl(cpu_val, t64);
5202 tcg_gen_ext32u_tl(cpu_val, cpu_val);
5203 gen_store_gpr(dc, rd + 1, cpu_val);
5204 tcg_gen_shri_i64(t64, t64, 32);
5205 tcg_gen_trunc_i64_tl(cpu_val, t64);
5206 tcg_gen_ext32u_tl(cpu_val, cpu_val);
5207 }
5208 break;
5209 case 0x9: /* ldsb, load signed byte */
5210 gen_address_mask(dc, cpu_addr);
5205 tcg_gen_trunc_i64_tl(cpu_val, t64);
5206 tcg_gen_ext32u_tl(cpu_val, cpu_val);
5207 gen_store_gpr(dc, rd + 1, cpu_val);
5208 tcg_gen_shri_i64(t64, t64, 32);
5209 tcg_gen_trunc_i64_tl(cpu_val, t64);
5210 tcg_gen_ext32u_tl(cpu_val, cpu_val);
5211 }
5212 break;
5213 case 0x9: /* ldsb, load signed byte */
5214 gen_address_mask(dc, cpu_addr);
5211 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
5215 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr, dc->mem_idx, MO_SB);
5212 break;
5213 case 0xa: /* ldsh, load signed halfword */
5214 gen_address_mask(dc, cpu_addr);
5216 break;
5217 case 0xa: /* ldsh, load signed halfword */
5218 gen_address_mask(dc, cpu_addr);
5215 tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
5219 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
5220 dc->mem_idx, MO_TESW);
5216 break;
5217 case 0xd: /* ldstub */
5218 gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
5219 break;
5220 case 0x0f:
5221 /* swap, swap register with memory. Also atomically */
5222 CHECK_IU_FEATURE(dc, SWAP);
5223 cpu_src1 = gen_load_gpr(dc, rd);

--- 37 unchanged lines hidden (view full) ---

5261 case 0x31: /* ldcsr */
5262 case 0x33: /* lddc */
5263 goto ncp_insn;
5264#endif
5265#endif
5266#ifdef TARGET_SPARC64
5267 case 0x08: /* V9 ldsw */
5268 gen_address_mask(dc, cpu_addr);
5221 break;
5222 case 0xd: /* ldstub */
5223 gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
5224 break;
5225 case 0x0f:
5226 /* swap, swap register with memory. Also atomically */
5227 CHECK_IU_FEATURE(dc, SWAP);
5228 cpu_src1 = gen_load_gpr(dc, rd);

--- 37 unchanged lines hidden (view full) ---

5266 case 0x31: /* ldcsr */
5267 case 0x33: /* lddc */
5268 goto ncp_insn;
5269#endif
5270#endif
5271#ifdef TARGET_SPARC64
5272 case 0x08: /* V9 ldsw */
5273 gen_address_mask(dc, cpu_addr);
5269 tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
5274 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
5275 dc->mem_idx, MO_TESL);
5270 break;
5271 case 0x0b: /* V9 ldx */
5272 gen_address_mask(dc, cpu_addr);
5276 break;
5277 case 0x0b: /* V9 ldx */
5278 gen_address_mask(dc, cpu_addr);
5273 tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
5279 tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
5280 dc->mem_idx, MO_TEUQ);
5274 break;
5275 case 0x18: /* V9 ldswa */
5276 gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
5277 break;
5278 case 0x1b: /* V9 ldxa */
5279 gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
5280 break;
5281 case 0x2d: /* V9 prefetch, no effect */

--- 82 unchanged lines hidden (view full) ---

5364 }
5365 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
5366 xop == 0xe || xop == 0x1e) {
5367 TCGv cpu_val = gen_load_gpr(dc, rd);
5368
5369 switch (xop) {
5370 case 0x4: /* st, store word */
5371 gen_address_mask(dc, cpu_addr);
5281 break;
5282 case 0x18: /* V9 ldswa */
5283 gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
5284 break;
5285 case 0x1b: /* V9 ldxa */
5286 gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
5287 break;
5288 case 0x2d: /* V9 prefetch, no effect */

--- 82 unchanged lines hidden (view full) ---

5371 }
5372 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
5373 xop == 0xe || xop == 0x1e) {
5374 TCGv cpu_val = gen_load_gpr(dc, rd);
5375
5376 switch (xop) {
5377 case 0x4: /* st, store word */
5378 gen_address_mask(dc, cpu_addr);
5372 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
5379 tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
5380 dc->mem_idx, MO_TEUL);
5373 break;
5374 case 0x5: /* stb, store byte */
5375 gen_address_mask(dc, cpu_addr);
5381 break;
5382 case 0x5: /* stb, store byte */
5383 gen_address_mask(dc, cpu_addr);
5376 tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
5384 tcg_gen_qemu_st_tl(cpu_val, cpu_addr, dc->mem_idx, MO_UB);
5377 break;
5378 case 0x6: /* sth, store halfword */
5379 gen_address_mask(dc, cpu_addr);
5385 break;
5386 case 0x6: /* sth, store halfword */
5387 gen_address_mask(dc, cpu_addr);
5380 tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
5388 tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
5389 dc->mem_idx, MO_TEUW);
5381 break;
5382 case 0x7: /* std, store double word */
5383 if (rd & 1)
5384 goto illegal_insn;
5385 else {
5386 TCGv_i64 t64;
5387 TCGv lo;
5388
5389 gen_address_mask(dc, cpu_addr);
5390 lo = gen_load_gpr(dc, rd + 1);
5391 t64 = tcg_temp_new_i64();
5392 tcg_gen_concat_tl_i64(t64, lo, cpu_val);
5390 break;
5391 case 0x7: /* std, store double word */
5392 if (rd & 1)
5393 goto illegal_insn;
5394 else {
5395 TCGv_i64 t64;
5396 TCGv lo;
5397
5398 gen_address_mask(dc, cpu_addr);
5399 lo = gen_load_gpr(dc, rd + 1);
5400 t64 = tcg_temp_new_i64();
5401 tcg_gen_concat_tl_i64(t64, lo, cpu_val);
5393 tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
5402 tcg_gen_qemu_st_i64(t64, cpu_addr,
5403 dc->mem_idx, MO_TEUQ);
5394 }
5395 break;
5396#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5397 case 0x14: /* sta, V9 stwa, store word alternate */
5398 gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
5399 break;
5400 case 0x15: /* stba, store byte alternate */
5401 gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);

--- 6 unchanged lines hidden (view full) ---

5408 goto illegal_insn;
5409 }
5410 gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
5411 break;
5412#endif
5413#ifdef TARGET_SPARC64
5414 case 0x0e: /* V9 stx */
5415 gen_address_mask(dc, cpu_addr);
5404 }
5405 break;
5406#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5407 case 0x14: /* sta, V9 stwa, store word alternate */
5408 gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
5409 break;
5410 case 0x15: /* stba, store byte alternate */
5411 gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);

--- 6 unchanged lines hidden (view full) ---

5418 goto illegal_insn;
5419 }
5420 gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
5421 break;
5422#endif
5423#ifdef TARGET_SPARC64
5424 case 0x0e: /* V9 stx */
5425 gen_address_mask(dc, cpu_addr);
5416 tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
5426 tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
5427 dc->mem_idx, MO_TEUQ);
5417 break;
5418 case 0x1e: /* V9 stxa */
5419 gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
5420 break;
5421#endif
5422 default:
5423 goto illegal_insn;
5424 }

--- 8 unchanged lines hidden (view full) ---

5433 tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
5434 dc->mem_idx, MO_TEUL);
5435 break;
5436 case 0x25: /* stfsr, V9 stxfsr */
5437 {
5438#ifdef TARGET_SPARC64
5439 gen_address_mask(dc, cpu_addr);
5440 if (rd == 1) {
5428 break;
5429 case 0x1e: /* V9 stxa */
5430 gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
5431 break;
5432#endif
5433 default:
5434 goto illegal_insn;
5435 }

--- 8 unchanged lines hidden (view full) ---

5444 tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
5445 dc->mem_idx, MO_TEUL);
5446 break;
5447 case 0x25: /* stfsr, V9 stxfsr */
5448 {
5449#ifdef TARGET_SPARC64
5450 gen_address_mask(dc, cpu_addr);
5451 if (rd == 1) {
5441 tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
5452 tcg_gen_qemu_st_tl(cpu_fsr, cpu_addr,
5453 dc->mem_idx, MO_TEUQ);
5442 break;
5443 }
5444#endif
5454 break;
5455 }
5456#endif
5445 tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
5457 tcg_gen_qemu_st_tl(cpu_fsr, cpu_addr,
5458 dc->mem_idx, MO_TEUL);
5446 }
5447 break;
5448 case 0x26:
5449#ifdef TARGET_SPARC64
5450 /* V9 stqf, store quad fpreg */
5451 CHECK_FPU_FEATURE(dc, FLOAT128);
5452 gen_address_mask(dc, cpu_addr);
5453 /* ??? While stqf only requires 4-byte alignment, it is

--- 361 unchanged lines hidden ---
5459 }
5460 break;
5461 case 0x26:
5462#ifdef TARGET_SPARC64
5463 /* V9 stqf, store quad fpreg */
5464 CHECK_FPU_FEATURE(dc, FLOAT128);
5465 gen_address_mask(dc, cpu_addr);
5466 /* ??? While stqf only requires 4-byte alignment, it is

--- 361 unchanged lines hidden ---