@@ -106,6 +106,8 @@ typedef enum AVRFeature {
AVR_FEATURE_RAMPX,
AVR_FEATURE_RAMPY,
AVR_FEATURE_RAMPZ,
+
+ AVR_FEATURE_LARGE_RAM,
} AVRFeature;
typedef struct CPUArchState {
@@ -1542,13 +1542,17 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
* M assumed to be in 0x000000ff format
* L assumed to be in 0x000000ff format
*/
-static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+static void gen_set_addr_short(TCGv addr, TCGv M, TCGv L)
{
-
tcg_gen_andi_tl(L, addr, 0x000000ff);
tcg_gen_andi_tl(M, addr, 0x0000ff00);
tcg_gen_shri_tl(M, M, 8);
+}
+
+static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+{
+ gen_set_addr_short(addr, M, L);
tcg_gen_andi_tl(H, addr, 0x00ff0000);
}
@@ -1563,9 +1567,13 @@ static void gen_set_yaddr(TCGv addr)
gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]);
}
-static void gen_set_zaddr(TCGv addr)
+static void gen_set_zaddr(DisasContext *ctx, TCGv addr, bool ram)
{
- gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+ if (!ram || avr_feature(ctx->env, AVR_FEATURE_LARGE_RAM)) {
+ gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+ } else {
+ gen_set_addr_short(addr, cpu_r[31], cpu_r[30]);
+ }
}
static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L)
@@ -1588,9 +1596,16 @@ static TCGv gen_get_yaddr(void)
return gen_get_addr(cpu_rampY, cpu_r[29], cpu_r[28]);
}
-static TCGv gen_get_zaddr(void)
+static TCGv gen_get_zaddr(DisasContext *ctx, bool ram)
{
- return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
+ if (!ram || avr_feature(ctx->env, AVR_FEATURE_LARGE_RAM)) {
+ return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
+ } else {
+ TCGv zero = tcg_const_i32(0);
+ TCGv res = gen_get_addr(zero, cpu_r[31], cpu_r[30]);
+ tcg_temp_free_i32(zero);
+ return res;
+ }
}
/*
@@ -1868,12 +1883,12 @@ static bool trans_LDDY(DisasContext *ctx, arg_LDDY *a)
static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a)
{
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
gen_data_load(ctx, Rd, addr);
tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
- gen_set_zaddr(addr);
+ gen_set_zaddr(ctx, addr, true);
tcg_temp_free_i32(addr);
@@ -1883,12 +1898,12 @@ static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a)
static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a)
{
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
gen_data_load(ctx, Rd, addr);
- gen_set_zaddr(addr);
+ gen_set_zaddr(ctx, addr, true);
tcg_temp_free_i32(addr);
@@ -1898,7 +1913,7 @@ static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a)
static bool trans_LDDZ(DisasContext *ctx, arg_LDDZ *a)
{
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
gen_data_load(ctx, Rd, addr);
@@ -2088,12 +2103,12 @@ static bool trans_STDY(DisasContext *ctx, arg_STDY *a)
static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a)
{
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
gen_data_store(ctx, Rd, addr);
tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
- gen_set_zaddr(addr);
+ gen_set_zaddr(ctx, addr, true);
tcg_temp_free_i32(addr);
@@ -2103,12 +2118,12 @@ static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a)
static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a)
{
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
gen_data_store(ctx, Rd, addr);
- gen_set_zaddr(addr);
+ gen_set_zaddr(ctx, addr, true);
tcg_temp_free_i32(addr);
@@ -2118,7 +2133,7 @@ static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a)
static bool trans_STDZ(DisasContext *ctx, arg_STDZ *a)
{
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
gen_data_store(ctx, Rd, addr);
@@ -2228,7 +2243,7 @@ static bool trans_ELPM1(DisasContext *ctx, arg_ELPM1 *a)
}
TCGv Rd = cpu_r[0];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, false);
tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */
@@ -2244,7 +2259,7 @@ static bool trans_ELPM2(DisasContext *ctx, arg_ELPM2 *a)
}
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, false);
tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */
@@ -2260,11 +2275,11 @@ static bool trans_ELPMX(DisasContext *ctx, arg_ELPMX *a)
}
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, false);
tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */
tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
- gen_set_zaddr(addr);
+ gen_set_zaddr(ctx, addr, false);
tcg_temp_free_i32(addr);
@@ -2402,7 +2417,7 @@ static bool trans_XCH(DisasContext *ctx, arg_XCH *a)
TCGv Rd = cpu_r[a->rd];
TCGv t0 = tcg_temp_new_i32();
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
gen_data_load(ctx, t0, addr);
gen_data_store(ctx, Rd, addr);
@@ -2432,7 +2447,7 @@ static bool trans_LAS(DisasContext *ctx, arg_LAS *a)
}
TCGv Rr = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
TCGv t0 = tcg_temp_new_i32();
TCGv t1 = tcg_temp_new_i32();
@@ -2467,7 +2482,7 @@ static bool trans_LAC(DisasContext *ctx, arg_LAC *a)
}
TCGv Rr = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
TCGv t0 = tcg_temp_new_i32();
TCGv t1 = tcg_temp_new_i32();
@@ -2502,7 +2517,7 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a)
}
TCGv Rd = cpu_r[a->rd];
- TCGv addr = gen_get_zaddr();
+ TCGv addr = gen_get_zaddr(ctx, true);
TCGv t0 = tcg_temp_new_i32();
TCGv t1 = tcg_temp_new_i32();