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 --- |