summaryrefslogtreecommitdiffstats
path: root/qemu/target-xtensa
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/target-xtensa')
-rw-r--r--qemu/target-xtensa/Makefile.objs1
-rw-r--r--qemu/target-xtensa/core-dc232b.c1
-rw-r--r--qemu/target-xtensa/core-dc233c.c1
-rw-r--r--qemu/target-xtensa/core-fsf.c1
-rw-r--r--qemu/target-xtensa/cpu.c9
-rw-r--r--qemu/target-xtensa/cpu.h6
-rw-r--r--qemu/target-xtensa/gdbstub.c10
-rw-r--r--qemu/target-xtensa/helper.c13
-rw-r--r--qemu/target-xtensa/monitor.c35
-rw-r--r--qemu/target-xtensa/op_helper.c25
-rw-r--r--qemu/target-xtensa/overlay_tool.h5
-rw-r--r--qemu/target-xtensa/translate.c166
-rw-r--r--qemu/target-xtensa/xtensa-semi.c7
13 files changed, 164 insertions, 116 deletions
diff --git a/qemu/target-xtensa/Makefile.objs b/qemu/target-xtensa/Makefile.objs
index 5c150a870..481de9197 100644
--- a/qemu/target-xtensa/Makefile.objs
+++ b/qemu/target-xtensa/Makefile.objs
@@ -2,5 +2,6 @@ obj-y += xtensa-semi.o
obj-y += core-dc232b.o
obj-y += core-dc233c.o
obj-y += core-fsf.o
+obj-$(CONFIG_SOFTMMU) += monitor.o
obj-y += translate.o op_helper.o helper.o cpu.o
obj-y += gdbstub.o
diff --git a/qemu/target-xtensa/core-dc232b.c b/qemu/target-xtensa/core-dc232b.c
index 06826c042..bb8ed4197 100644
--- a/qemu/target-xtensa/core-dc232b.c
+++ b/qemu/target-xtensa/core-dc232b.c
@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
diff --git a/qemu/target-xtensa/core-dc233c.c b/qemu/target-xtensa/core-dc233c.c
index 8daf7d9f8..40475e520 100644
--- a/qemu/target-xtensa/core-dc233c.c
+++ b/qemu/target-xtensa/core-dc233c.c
@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
diff --git a/qemu/target-xtensa/core-fsf.c b/qemu/target-xtensa/core-fsf.c
index f6ea6b944..15ef470e8 100644
--- a/qemu/target-xtensa/core-fsf.c
+++ b/qemu/target-xtensa/core-fsf.c
@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
diff --git a/qemu/target-xtensa/cpu.c b/qemu/target-xtensa/cpu.c
index da8129db5..01b251fdc 100644
--- a/qemu/target-xtensa/cpu.c
+++ b/qemu/target-xtensa/cpu.c
@@ -28,6 +28,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "cpu.h"
#include "qemu-common.h"
#include "migration/vmstate.h"
@@ -155,6 +157,13 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->debug_excp_handler = xtensa_breakpoint_handler;
dc->vmsd = &vmstate_xtensa_cpu;
+
+ /*
+ * Reason: xtensa_cpu_initfn() calls cpu_exec_init(), which saves
+ * the object in cpus -> dangling pointer after final
+ * object_unref().
+ */
+ dc->cannot_destroy_with_object_finalize_yet = true;
}
static const TypeInfo xtensa_cpu_type_info = {
diff --git a/qemu/target-xtensa/cpu.h b/qemu/target-xtensa/cpu.h
index 96bfc82e9..d0bd9dada 100644
--- a/qemu/target-xtensa/cpu.h
+++ b/qemu/target-xtensa/cpu.h
@@ -30,11 +30,9 @@
#define ALIGNED_ONLY
#define TARGET_LONG_BITS 32
-#define ELF_MACHINE EM_XTENSA
#define CPUArchState struct CPUXtensaState
-#include "config.h"
#include "qemu-common.h"
#include "exec/cpu-defs.h"
#include "fpu/softfloat.h"
@@ -65,6 +63,7 @@ enum {
XTENSA_OPTION_MP_SYNCHRO,
XTENSA_OPTION_CONDITIONAL_STORE,
XTENSA_OPTION_ATOMCTL,
+ XTENSA_OPTION_DEPBITS,
/* Interrupts and exceptions */
XTENSA_OPTION_EXCEPTION,
@@ -383,7 +382,6 @@ typedef struct CPUXtensaState {
#include "cpu-qom.h"
#define cpu_exec cpu_xtensa_exec
-#define cpu_gen_code cpu_xtensa_gen_code
#define cpu_signal_handler cpu_xtensa_signal_handler
#define cpu_list xtensa_cpu_list
@@ -492,7 +490,7 @@ static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
#define MMU_MODE2_SUFFIX _ring2
#define MMU_MODE3_SUFFIX _ring3
-static inline int cpu_mmu_index(CPUXtensaState *env)
+static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
{
return xtensa_get_cring(env);
}
diff --git a/qemu/target-xtensa/gdbstub.c b/qemu/target-xtensa/gdbstub.c
index bc2e1b55f..51d4db083 100644
--- a/qemu/target-xtensa/gdbstub.c
+++ b/qemu/target-xtensa/gdbstub.c
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "exec/gdbstub.h"
@@ -63,8 +63,8 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);
default:
- qemu_log("%s from reg %d of unsupported type %d\n",
- __func__, n, reg->type);
+ qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported type %d\n",
+ __func__, n, reg->type);
return 0;
}
}
@@ -117,8 +117,8 @@ int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
break;
default:
- qemu_log("%s to reg %d of unsupported type %d\n",
- __func__, n, reg->type);
+ qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported type %d\n",
+ __func__, n, reg->type);
return 0;
}
diff --git a/qemu/target-xtensa/helper.c b/qemu/target-xtensa/helper.c
index 76be50d09..839f4a74a 100644
--- a/qemu/target-xtensa/helper.c
+++ b/qemu/target-xtensa/helper.c
@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
@@ -254,8 +255,8 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
env->config->exception_vector[cs->exception_index]);
env->exception_taken = 1;
} else {
- qemu_log("%s(pc = %08x) bad exception_index: %d\n",
- __func__, env->pc, cs->exception_index);
+ qemu_log_mask(CPU_LOG_INT, "%s(pc = %08x) bad exception_index: %d\n",
+ __func__, env->pc, cs->exception_index);
}
break;
@@ -541,8 +542,8 @@ static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
wi = ++env->autorefill_idx & 0x3;
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);
env->sregs[EXCVADDR] = vaddr;
- qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
- __func__, vaddr, vpn, pte);
+ qemu_log_mask(CPU_LOG_MMU, "%s: autorefill(%08x): %08x -> %08x\n",
+ __func__, vaddr, vpn, pte);
} else {
xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);
entry = &tmp_entry;
@@ -590,8 +591,8 @@ static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte)
int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0,
&paddr, &page_size, &access, false);
- qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__,
- vaddr, ret ? ~0 : paddr);
+ qemu_log_mask(CPU_LOG_MMU, "%s: trying autorefill(%08x) -> %08x\n",
+ __func__, vaddr, ret ? ~0 : paddr);
if (ret == 0) {
*pte = ldl_phys(cs->as, paddr);
diff --git a/qemu/target-xtensa/monitor.c b/qemu/target-xtensa/monitor.c
new file mode 100644
index 000000000..f3fa4cd27
--- /dev/null
+++ b/qemu/target-xtensa/monitor.c
@@ -0,0 +1,35 @@
+/*
+ * QEMU monitor
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "monitor/monitor.h"
+#include "monitor/hmp-target.h"
+#include "hmp.h"
+
+void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+{
+ CPUArchState *env1 = mon_get_cpu_env();
+
+ dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
+}
diff --git a/qemu/target-xtensa/op_helper.c b/qemu/target-xtensa/op_helper.c
index be657e615..62fa33d8d 100644
--- a/qemu/target-xtensa/op_helper.c
+++ b/qemu/target-xtensa/op_helper.c
@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
@@ -57,8 +58,8 @@ void tlb_fill(CPUState *cs,
int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
&paddr, &page_size, &access);
- qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__,
- vaddr, is_write, mmu_idx, paddr, ret);
+ qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
+ __func__, vaddr, is_write, mmu_idx, paddr, ret);
if (ret == 0) {
tlb_set_page(cs,
@@ -245,8 +246,8 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
{
int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT;
if (s > 3 || ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
- qemu_log("Illegal entry instruction(pc = %08x), PS = %08x\n",
- pc, env->sregs[PS]);
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal entry instruction(pc = %08x), PS = %08x\n",
+ pc, env->sregs[PS]);
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
} else {
uint32_t windowstart = xtensa_replicate_windowstart(env) >>
@@ -307,9 +308,9 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
if (n == 0 || (m != 0 && m != n) ||
((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
- qemu_log("Illegal retw instruction(pc = %08x), "
- "PS = %08x, m = %d, n = %d\n",
- pc, env->sregs[PS], m, n);
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal retw instruction(pc = %08x), "
+ "PS = %08x, m = %d, n = %d\n",
+ pc, env->sregs[PS], m, n);
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
} else {
int owb = windowbase;
@@ -743,8 +744,8 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
xtensa_tlb_set_entry_mmu(env, entry, dtlb, wi, ei, vpn, pte);
tlb_flush_page(cs, entry->vaddr);
} else {
- qemu_log("%s %d, %d, %d trying to set immutable entry\n",
- __func__, dtlb, wi, ei);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s %d, %d, %d trying to set immutable entry\n",
+ __func__, dtlb, wi, ei);
}
} else {
tlb_flush_page(cs, entry->vaddr);
@@ -806,15 +807,15 @@ static void set_dbreak(CPUXtensaState *env, unsigned i, uint32_t dbreaka,
}
/* contiguous mask after inversion is one less than some power of 2 */
if ((~mask + 1) & ~mask) {
- qemu_log("DBREAKC mask is not contiguous: 0x%08x\n", dbreakc);
+ qemu_log_mask(LOG_GUEST_ERROR, "DBREAKC mask is not contiguous: 0x%08x\n", dbreakc);
/* cut mask after the first zero bit */
mask = 0xffffffff << (32 - clo32(mask));
}
if (cpu_watchpoint_insert(cs, dbreaka & mask, ~mask + 1,
flags, &env->cpu_watchpoint[i])) {
env->cpu_watchpoint[i] = NULL;
- qemu_log("Failed to set data breakpoint at 0x%08x/%d\n",
- dbreaka & mask, ~mask + 1);
+ qemu_log_mask(LOG_GUEST_ERROR, "Failed to set data breakpoint at 0x%08x/%d\n",
+ dbreaka & mask, ~mask + 1);
}
}
diff --git a/qemu/target-xtensa/overlay_tool.h b/qemu/target-xtensa/overlay_tool.h
index eda03aaca..e8a7fda3d 100644
--- a/qemu/target-xtensa/overlay_tool.h
+++ b/qemu/target-xtensa/overlay_tool.h
@@ -30,6 +30,10 @@
{ .targno = (no), .type = (typ), .group = (grp), .size = (sz) },
#define XTREG_END { .targno = -1 },
+#ifndef XCHAL_HAVE_DEPBITS
+#define XCHAL_HAVE_DEPBITS 0
+#endif
+
#ifndef XCHAL_HAVE_DIV32
#define XCHAL_HAVE_DIV32 0
#endif
@@ -69,6 +73,7 @@
XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \
XTENSA_OPTION_ATOMCTL) | \
+ XCHAL_OPTION(XCHAL_HAVE_DEPBITS, XTENSA_OPTION_DEPBITS) | \
/* Interrupts and exceptions */ \
XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \
XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \
diff --git a/qemu/target-xtensa/translate.c b/qemu/target-xtensa/translate.c
index f2118c24c..989448846 100644
--- a/qemu/target-xtensa/translate.c
+++ b/qemu/target-xtensa/translate.c
@@ -28,7 +28,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <stdio.h>
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
@@ -43,6 +43,7 @@
#include "exec/helper-gen.h"
#include "trace-tcg.h"
+#include "exec/log.h"
typedef struct DisasContext {
@@ -73,7 +74,7 @@ typedef struct DisasContext {
unsigned cpenable;
} DisasContext;
-static TCGv_ptr cpu_env;
+static TCGv_env cpu_env;
static TCGv_i32 cpu_pc;
static TCGv_i32 cpu_R[16];
static TCGv_i32 cpu_FR[16];
@@ -217,24 +218,24 @@ void xtensa_translate_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_pc = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, pc), "pc");
for (i = 0; i < 16; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, regs[i]),
regnames[i]);
}
for (i = 0; i < 16; i++) {
- cpu_FR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, fregs[i].f32[FP_F32_LOW]),
fregnames[i]);
}
for (i = 0; i < 256; ++i) {
if (sregnames[i].name) {
- cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, sregs[i]),
sregnames[i].name);
}
@@ -242,7 +243,7 @@ void xtensa_translate_init(void)
for (i = 0; i < 256; ++i) {
if (uregnames[i].name) {
- cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUXtensaState, uregs[i]),
uregnames[i].name);
}
@@ -501,9 +502,9 @@ static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
{
if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
if (sregnames[sr].name) {
- qemu_log("SR %s is not configured\n", sregnames[sr].name);
+ qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name);
} else {
- qemu_log("SR %d is not implemented\n", sr);
+ qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr);
}
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
return false;
@@ -514,8 +515,8 @@ static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
[SR_X] = "xsr",
};
assert(access < ARRAY_SIZE(access_text) && access_text[access]);
- qemu_log("SR %s is not available for %s\n", sregnames[sr].name,
- access_text[access]);
+ qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name,
+ access_text[access]);
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
return false;
}
@@ -875,18 +876,18 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
{
#define HAS_OPTION_BITS(opt) do { \
if (!option_bits_enabled(dc, opt)) { \
- qemu_log("Option is not enabled %s:%d\n", \
- __FILE__, __LINE__); \
+ qemu_log_mask(LOG_GUEST_ERROR, "Option is not enabled %s:%d\n", \
+ __FILE__, __LINE__); \
goto invalid_opcode; \
} \
} while (0)
#define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))
-#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
+#define TBD() qemu_log_mask(LOG_UNIMP, "TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
#define RESERVED() do { \
- qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
- dc->pc, b0, b1, b2, __FILE__, __LINE__); \
+ qemu_log_mask(LOG_GUEST_ERROR, "RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
+ dc->pc, b0, b1, b2, __FILE__, __LINE__); \
goto invalid_opcode; \
} while (0)
@@ -1186,7 +1187,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);
}
} else {
- qemu_log("RFI %d is illegal\n", RRR_S);
+ qemu_log_mask(LOG_GUEST_ERROR, "RFI %d is illegal\n", RRR_S);
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
}
break;
@@ -1222,7 +1223,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
gen_helper_simcall(cpu_env);
}
} else {
- qemu_log("SIMCALL but semihosting is disabled\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
}
break;
@@ -1544,7 +1545,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
TCGv_i64 tmp = tcg_temp_new_i64(); \
tcg_gen_extu_i32_i64(tmp, reg); \
tcg_gen_##cmd##_i64(v, v, tmp); \
- tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
+ tcg_gen_extrl_i64_i32(cpu_R[RRR_R], v); \
tcg_temp_free_i64(v); \
tcg_temp_free_i64(tmp); \
} while (0)
@@ -1865,7 +1866,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
if (uregnames[st].name) {
tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
} else {
- qemu_log("RUR %d not implemented, ", st);
+ qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", st);
TBD();
}
}
@@ -1876,7 +1877,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
if (uregnames[RSR_SR].name) {
gen_wur(RSR_SR, cpu_R[RRR_T]);
} else {
- qemu_log("WUR %d not implemented, ", RSR_SR);
+ qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", RSR_SR);
TBD();
}
}
@@ -1943,7 +1944,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
switch (OP2) {
case 0: /*L32E*/
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
- if (gen_check_privilege(dc)) {
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, RRR_S, RRR_T)) {
TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRR_S],
(0xffffffc0 | (RRR_R << 2)));
@@ -1954,7 +1956,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 4: /*S32E*/
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
- if (gen_check_privilege(dc)) {
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, RRR_S, RRR_T)) {
TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRR_S],
(0xffffffc0 | (RRR_R << 2)));
@@ -1963,6 +1966,17 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
}
break;
+ case 5: /*S32N*/
+ if (gen_window_check2(dc, RRI4_S, RRI4_T)) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(addr, cpu_R[RRI4_S], RRI4_IMM4 << 2);
+ gen_load_store_alignment(dc, 2, addr, false);
+ tcg_gen_qemu_st32(cpu_R[RRI4_T], addr, dc->cring);
+ tcg_temp_free(addr);
+ }
+ break;
+
default:
RESERVED();
break;
@@ -1970,6 +1984,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break;
case 10: /*FP0*/
+ /*DEPBITS*/
+ if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) {
+ if (!gen_window_check2(dc, RRR_S, RRR_T)) {
+ break;
+ }
+ tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S],
+ OP2, RRR_R + 1);
+ break;
+ }
+
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
switch (OP2) {
case 0: /*ADD.Sf*/
@@ -2104,6 +2128,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break;
case 11: /*FP1*/
+ /*DEPBITS*/
+ if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) {
+ if (!gen_window_check2(dc, RRR_S, RRR_T)) {
+ break;
+ }
+ tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S],
+ OP2 + 16, RRR_R + 1);
+ break;
+ }
+
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
#define gen_compare(rel, br, a, b) \
@@ -2973,7 +3007,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
return;
invalid_opcode:
- qemu_log("INVALID(pc = %08x)\n", dc->pc);
+ qemu_log_mask(LOG_GUEST_ERROR, "INVALID(pc = %08x)\n", dc->pc);
gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
#undef HAS_OPTION
}
@@ -2984,22 +3018,6 @@ static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
return xtensa_op0_insn_len(OP0);
}
-static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
-{
- CPUState *cs = CPU(xtensa_env_get_cpu(env));
- CPUBreakpoint *bp;
-
- if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
- QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
- if (bp->pc == dc->pc) {
- tcg_gen_movi_i32(cpu_pc, dc->pc);
- gen_exception(dc, EXCP_DEBUG);
- dc->is_jmp = DISAS_UPDATE;
- }
- }
- }
-}
-
static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
{
unsigned i;
@@ -3013,15 +3031,12 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
}
}
-static inline
-void gen_intermediate_code_internal(XtensaCPU *cpu,
- TranslationBlock *tb, bool search_pc)
+void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
{
+ XtensaCPU *cpu = xtensa_env_get_cpu(env);
CPUState *cs = CPU(cpu);
- CPUXtensaState *env = &cpu->env;
DisasContext dc;
int insn_count = 0;
- int j, lj = -1;
int max_insns = tb->cflags & CF_COUNT_MASK;
uint32_t pc_start = tb->pc;
uint32_t next_page_start =
@@ -3030,6 +3045,9 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
if (max_insns == 0) {
max_insns = CF_COUNT_MASK;
}
+ if (max_insns > TCG_MAX_INSNS) {
+ max_insns = TCG_MAX_INSNS;
+ }
dc.config = env->config;
dc.singlestep_enabled = cs->singlestep_enabled;
@@ -3062,28 +3080,24 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
}
do {
- check_breakpoint(env, &dc);
+ tcg_gen_insn_start(dc.pc);
+ ++insn_count;
- if (search_pc) {
- j = tcg_op_buf_count();
- if (lj < j) {
- lj++;
- while (lj < j) {
- tcg_ctx.gen_opc_instr_start[lj++] = 0;
- }
- }
- tcg_ctx.gen_opc_pc[lj] = dc.pc;
- tcg_ctx.gen_opc_instr_start[lj] = 1;
- tcg_ctx.gen_opc_icount[lj] = insn_count;
- }
+ ++dc.ccount_delta;
- if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
- tcg_gen_debug_insn_start(dc.pc);
+ if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
+ tcg_gen_movi_i32(cpu_pc, dc.pc);
+ gen_exception(&dc, EXCP_DEBUG);
+ dc.is_jmp = DISAS_UPDATE;
+ /* The address covered by the breakpoint must be included in
+ [tb->pc, tb->pc + tb->size) in order to for it to be
+ properly cleared -- thus we increment the PC here so that
+ the logic setting tb->size below does the right thing. */
+ dc.pc += 2;
+ break;
}
- ++dc.ccount_delta;
-
- if (insn_count + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
+ if (insn_count == max_insns && (tb->cflags & CF_LAST_IO)) {
gen_io_start();
}
@@ -3104,7 +3118,6 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
}
disas_xtensa_insn(env, &dc);
- ++insn_count;
if (dc.icount) {
tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
}
@@ -3142,24 +3155,8 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
qemu_log("\n");
}
#endif
- if (search_pc) {
- j = tcg_op_buf_count();
- memset(tcg_ctx.gen_opc_instr_start + lj + 1, 0,
- (j - lj) * sizeof(tcg_ctx.gen_opc_instr_start[0]));
- } else {
- tb->size = dc.pc - pc_start;
- tb->icount = insn_count;
- }
-}
-
-void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
-{
- gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, false);
-}
-
-void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
-{
- gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, true);
+ tb->size = dc.pc - pc_start;
+ tb->icount = insn_count;
}
void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
@@ -3213,7 +3210,8 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
}
}
-void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, int pc_pos)
+void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
+ target_ulong *data)
{
- env->pc = tcg_ctx.gen_opc_pc[pc_pos];
+ env->pc = data[0];
}
diff --git a/qemu/target-xtensa/xtensa-semi.c b/qemu/target-xtensa/xtensa-semi.c
index 16e9d8c7b..370e365c6 100644
--- a/qemu/target-xtensa/xtensa-semi.c
+++ b/qemu/target-xtensa/xtensa-semi.c
@@ -25,10 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stddef.h>
+#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "qemu/log.h"
@@ -313,7 +310,7 @@ void HELPER(simcall)(CPUXtensaState *env)
break;
default:
- qemu_log("%s(%d): not implemented\n", __func__, regs[2]);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s(%d): not implemented\n", __func__, regs[2]);
regs[2] = -1;
regs[3] = TARGET_ENOSYS;
break;