508 changes: 266 additions & 242 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter.h

Large diffs are not rendered by default.

90 changes: 50 additions & 40 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp
Expand Up @@ -12,101 +12,110 @@
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"

void Interpreter::bx(UGeckoInstruction inst)
void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
{
auto& ppc_state = interpreter.m_ppc_state;

if (inst.LK)
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
LR(ppc_state) = ppc_state.pc + 4;

const auto address = u32(SignExt26(inst.LI << 2));

if (inst.AA)
PowerPC::ppcState.npc = address;
ppc_state.npc = address;
else
PowerPC::ppcState.npc = PowerPC::ppcState.pc + address;
ppc_state.npc = ppc_state.pc + address;

m_end_block = true;
interpreter.m_end_block = true;
}

// bcx - ugly, straight from PPC manual equations :)
void Interpreter::bcx(UGeckoInstruction inst)
void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
{
auto& ppc_state = interpreter.m_ppc_state;

if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR(PowerPC::ppcState)--;
CTR(ppc_state)--;

const bool true_false = ((inst.BO >> 3) & 1) != 0;
const bool only_counter_check = ((inst.BO >> 4) & 1) != 0;
const bool only_condition_check = ((inst.BO >> 2) & 1) != 0;
const u32 ctr_check = ((CTR(PowerPC::ppcState) != 0) ^ (inst.BO >> 1)) & 1;
const u32 ctr_check = ((CTR(ppc_state) != 0) ^ (inst.BO >> 1)) & 1;
const bool counter = only_condition_check || ctr_check != 0;
const bool condition =
only_counter_check || (PowerPC::ppcState.cr.GetBit(inst.BI) == u32(true_false));
const bool condition = only_counter_check || (ppc_state.cr.GetBit(inst.BI) == u32(true_false));

if (counter && condition)
{
if (inst.LK)
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
LR(ppc_state) = ppc_state.pc + 4;

const auto address = u32(SignExt16(s16(inst.BD << 2)));

if (inst.AA)
PowerPC::ppcState.npc = address;
ppc_state.npc = address;
else
PowerPC::ppcState.npc = PowerPC::ppcState.pc + address;
ppc_state.npc = ppc_state.pc + address;
}

m_end_block = true;
interpreter.m_end_block = true;
}

void Interpreter::bcctrx(UGeckoInstruction inst)
void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
{
auto& ppc_state = interpreter.m_ppc_state;

DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0,
"bcctrx with decrement and test CTR option is invalid!");

const u32 condition =
((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
((inst.BO_2 >> 4) | (ppc_state.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;

if (condition != 0)
{
PowerPC::ppcState.npc = CTR(PowerPC::ppcState) & (~3);
ppc_state.npc = CTR(ppc_state) & (~3);
if (inst.LK_3)
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
LR(ppc_state) = ppc_state.pc + 4;
}

m_end_block = true;
interpreter.m_end_block = true;
}

void Interpreter::bclrx(UGeckoInstruction inst)
void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
{
auto& ppc_state = interpreter.m_ppc_state;

if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
CTR(PowerPC::ppcState)--;
CTR(ppc_state)--;

const u32 counter = ((inst.BO_2 >> 2) | ((CTR(PowerPC::ppcState) != 0) ^ (inst.BO_2 >> 1))) & 1;
const u32 counter = ((inst.BO_2 >> 2) | ((CTR(ppc_state) != 0) ^ (inst.BO_2 >> 1))) & 1;
const u32 condition =
((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
((inst.BO_2 >> 4) | (ppc_state.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;

if ((counter & condition) != 0)
{
PowerPC::ppcState.npc = LR(PowerPC::ppcState) & (~3);
ppc_state.npc = LR(ppc_state) & (~3);
if (inst.LK_3)
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
LR(ppc_state) = ppc_state.pc + 4;
}

m_end_block = true;
interpreter.m_end_block = true;
}

void Interpreter::HLEFunction(UGeckoInstruction inst)
void Interpreter::HLEFunction(Interpreter& interpreter, UGeckoInstruction inst)
{
m_end_block = true;
interpreter.m_end_block = true;

ASSERT(Core::IsCPUThread());
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(interpreter.m_system);

HLE::Execute(guard, PowerPC::ppcState.pc, inst.hex);
HLE::Execute(guard, interpreter.m_ppc_state.pc, inst.hex);
}

void Interpreter::rfi(UGeckoInstruction inst)
void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
{
if (PowerPC::ppcState.msr.PR)
auto& ppc_state = interpreter.m_ppc_state;

if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
return;
Expand All @@ -115,26 +124,27 @@ void Interpreter::rfi(UGeckoInstruction inst)
// Restore saved bits from SRR1 to MSR.
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
const u32 mask = 0x87C0FFFF;
PowerPC::ppcState.msr.Hex =
(PowerPC::ppcState.msr.Hex & ~mask) | (SRR1(PowerPC::ppcState) & mask);
ppc_state.msr.Hex = (ppc_state.msr.Hex & ~mask) | (SRR1(ppc_state) & mask);
// MSR[13] is set to 0.
PowerPC::ppcState.msr.Hex &= 0xFFFBFFFF;
ppc_state.msr.Hex &= 0xFFFBFFFF;
// Here we should check if there are pending exceptions, and if their corresponding enable bits
// are set
// if above is true, we'd do:
// PowerPC::CheckExceptions();
// else
// set NPC to saved offset and resume
PowerPC::ppcState.npc = SRR0(PowerPC::ppcState);
m_end_block = true;
ppc_state.npc = SRR0(ppc_state);
interpreter.m_end_block = true;
}

// sc isn't really used for anything important in GameCube games (just for a write barrier) so we
// really don't have to emulate it.
// We do it anyway, though :P
void Interpreter::sc(UGeckoInstruction inst)
void Interpreter::sc(Interpreter& interpreter, UGeckoInstruction inst)
{
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
auto& ppc_state = interpreter.m_ppc_state;

ppc_state.Exceptions |= EXCEPTION_SYSCALL;
PowerPC::CheckExceptions();
m_end_block = true;
interpreter.m_end_block = true;
}
550 changes: 287 additions & 263 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp

Large diffs are not rendered by default.

526 changes: 286 additions & 240 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp

Large diffs are not rendered by default.

639 changes: 353 additions & 286 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp

Large diffs are not rendered by default.

Expand Up @@ -308,104 +308,112 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI,
ppcs->ps[instRD].SetBoth(ps0, ps1);
}

void Interpreter::psq_l(UGeckoInstruction inst)
void Interpreter::psq_l(Interpreter& interpreter, UGeckoInstruction inst)
{
if (HID2(PowerPC::ppcState).LSQE == 0)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
return;
}

const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12);
Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W);
const u32 EA = inst.RA ? (ppc_state.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12);
Helper_Dequantize(&ppc_state, EA, inst.I, inst.RD, inst.W);
}

void Interpreter::psq_lu(UGeckoInstruction inst)
void Interpreter::psq_lu(Interpreter& interpreter, UGeckoInstruction inst)
{
if (HID2(PowerPC::ppcState).LSQE == 0)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
return;
}

const u32 EA = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12);
Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W);
const u32 EA = ppc_state.gpr[inst.RA] + u32(inst.SIMM_12);
Helper_Dequantize(&ppc_state, EA, inst.I, inst.RD, inst.W);

if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
{
return;
}

PowerPC::ppcState.gpr[inst.RA] = EA;
ppc_state.gpr[inst.RA] = EA;
}

void Interpreter::psq_st(UGeckoInstruction inst)
void Interpreter::psq_st(Interpreter& interpreter, UGeckoInstruction inst)
{
if (HID2(PowerPC::ppcState).LSQE == 0)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
return;
}

const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12);
Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W);
const u32 EA = inst.RA ? (ppc_state.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12);
Helper_Quantize(&ppc_state, EA, inst.I, inst.RS, inst.W);
}

void Interpreter::psq_stu(UGeckoInstruction inst)
void Interpreter::psq_stu(Interpreter& interpreter, UGeckoInstruction inst)
{
if (HID2(PowerPC::ppcState).LSQE == 0)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
return;
}

const u32 EA = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12);
Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W);
const u32 EA = ppc_state.gpr[inst.RA] + u32(inst.SIMM_12);
Helper_Quantize(&ppc_state, EA, inst.I, inst.RS, inst.W);

if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
{
return;
}

PowerPC::ppcState.gpr[inst.RA] = EA;
ppc_state.gpr[inst.RA] = EA;
}

void Interpreter::psq_lx(UGeckoInstruction inst)
void Interpreter::psq_lx(Interpreter& interpreter, UGeckoInstruction inst)
{
const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]) :
PowerPC::ppcState.gpr[inst.RB];
Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx);
auto& ppc_state = interpreter.m_ppc_state;
const u32 EA =
inst.RA ? (ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB]) : ppc_state.gpr[inst.RB];
Helper_Dequantize(&ppc_state, EA, inst.Ix, inst.RD, inst.Wx);
}

void Interpreter::psq_stx(UGeckoInstruction inst)
void Interpreter::psq_stx(Interpreter& interpreter, UGeckoInstruction inst)
{
const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]) :
PowerPC::ppcState.gpr[inst.RB];
Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx);
auto& ppc_state = interpreter.m_ppc_state;
const u32 EA =
inst.RA ? (ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB]) : ppc_state.gpr[inst.RB];
Helper_Quantize(&ppc_state, EA, inst.Ix, inst.RS, inst.Wx);
}

void Interpreter::psq_lux(UGeckoInstruction inst)
void Interpreter::psq_lux(Interpreter& interpreter, UGeckoInstruction inst)
{
const u32 EA = PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB];
Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx);
auto& ppc_state = interpreter.m_ppc_state;
const u32 EA = ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB];
Helper_Dequantize(&ppc_state, EA, inst.Ix, inst.RD, inst.Wx);

if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
{
return;
}

PowerPC::ppcState.gpr[inst.RA] = EA;
ppc_state.gpr[inst.RA] = EA;
}

void Interpreter::psq_stux(UGeckoInstruction inst)
void Interpreter::psq_stux(Interpreter& interpreter, UGeckoInstruction inst)
{
const u32 EA = PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB];
Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx);
auto& ppc_state = interpreter.m_ppc_state;
const u32 EA = ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB];
Helper_Quantize(&ppc_state, EA, inst.Ix, inst.RS, inst.Wx);

if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
{
return;
}

PowerPC::ppcState.gpr[inst.RA] = EA;
ppc_state.gpr[inst.RA] = EA;
}
514 changes: 260 additions & 254 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp

Large diffs are not rendered by default.

328 changes: 174 additions & 154 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp
Expand Up @@ -468,29 +468,29 @@ Interpreter::Instruction Interpreter::GetInterpreterOp(UGeckoInstruction inst)
return result;
}

void Interpreter::RunInterpreterOp(UGeckoInstruction inst)
void Interpreter::RunInterpreterOp(Interpreter& interpreter, UGeckoInstruction inst)
{
// Will handle subtables using RunTable4 etc.
s_interpreter_op_table[inst.OPCD](inst);
s_interpreter_op_table[inst.OPCD](interpreter, inst);
}

void Interpreter::RunTable4(UGeckoInstruction inst)
void Interpreter::RunTable4(Interpreter& interpreter, UGeckoInstruction inst)
{
s_interpreter_op_table4[inst.SUBOP10](inst);
s_interpreter_op_table4[inst.SUBOP10](interpreter, inst);
}
void Interpreter::RunTable19(UGeckoInstruction inst)
void Interpreter::RunTable19(Interpreter& interpreter, UGeckoInstruction inst)
{
s_interpreter_op_table19[inst.SUBOP10](inst);
s_interpreter_op_table19[inst.SUBOP10](interpreter, inst);
}
void Interpreter::RunTable31(UGeckoInstruction inst)
void Interpreter::RunTable31(Interpreter& interpreter, UGeckoInstruction inst)
{
s_interpreter_op_table31[inst.SUBOP10](inst);
s_interpreter_op_table31[inst.SUBOP10](interpreter, inst);
}
void Interpreter::RunTable59(UGeckoInstruction inst)
void Interpreter::RunTable59(Interpreter& interpreter, UGeckoInstruction inst)
{
s_interpreter_op_table59[inst.SUBOP5](inst);
s_interpreter_op_table59[inst.SUBOP5](interpreter, inst);
}
void Interpreter::RunTable63(UGeckoInstruction inst)
void Interpreter::RunTable63(Interpreter& interpreter, UGeckoInstruction inst)
{
s_interpreter_op_table63[inst.SUBOP10](inst);
s_interpreter_op_table63[inst.SUBOP10](interpreter, inst);
}
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/Jit64/Jit.cpp
Expand Up @@ -344,7 +344,7 @@ void Jit64::FallBackToInterpreter(UGeckoInstruction inst)

Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst);
ABI_PushRegistersAndAdjustStack({}, 0);
ABI_CallFunctionC(instr, inst.hex);
ABI_CallFunctionPC(instr, &Core::System::GetInstance().GetInterpreter(), inst.hex);
ABI_PopRegistersAndAdjustStack({}, 0);

// If the instruction wrote to any registers which were marked as discarded,
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/PowerPC/JitArm64/Jit.cpp
Expand Up @@ -199,7 +199,8 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)

Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst);
MOVP2R(ARM64Reg::X8, instr);
MOVI2R(ARM64Reg::W0, inst.hex);
MOVP2R(ARM64Reg::W0, &Core::System::GetInstance().GetInterpreter());
MOVI2R(ARM64Reg::W1, inst.hex);
BLR(ARM64Reg::X8);

// If the instruction wrote to any registers which were marked as discarded,
Expand Down
17 changes: 10 additions & 7 deletions Source/Core/Core/PowerPC/PowerPC.cpp
Expand Up @@ -40,7 +40,6 @@ PowerPCState ppcState;

static CPUCoreBase* s_cpu_core_base = nullptr;
static bool s_cpu_core_base_is_injected = false;
Interpreter* const s_interpreter = Interpreter::getInstance();
static CoreMode s_mode = CoreMode::Interpreter;

BreakPoints breakpoints;
Expand Down Expand Up @@ -220,12 +219,13 @@ static void InitializeCPUCore(CPUCore cpu_core)
{
// We initialize the interpreter because
// it is used on boot and code window independently.
s_interpreter->Init();
auto& interpreter = Core::System::GetInstance().GetInterpreter();
interpreter.Init();

switch (cpu_core)
{
case CPUCore::Interpreter:
s_cpu_core_base = s_interpreter;
s_cpu_core_base = &interpreter;
break;

default:
Expand All @@ -239,7 +239,7 @@ static void InitializeCPUCore(CPUCore cpu_core)
break;
}

s_mode = s_cpu_core_base == s_interpreter ? CoreMode::Interpreter : CoreMode::JIT;
s_mode = s_cpu_core_base == &interpreter ? CoreMode::Interpreter : CoreMode::JIT;
}

const std::vector<CPUCore>& AvailableCPUCores()
Expand Down Expand Up @@ -316,7 +316,8 @@ void Shutdown()
{
InjectExternalCPUCore(nullptr);
JitInterface::Shutdown();
s_interpreter->Shutdown();
auto& interpreter = Core::System::GetInstance().GetInterpreter();
interpreter.Shutdown();
s_cpu_core_base = nullptr;
}

Expand All @@ -327,17 +328,19 @@ CoreMode GetMode()

static void ApplyMode()
{
auto& interpreter = Core::System::GetInstance().GetInterpreter();

switch (s_mode)
{
case CoreMode::Interpreter: // Switching from JIT to interpreter
s_cpu_core_base = s_interpreter;
s_cpu_core_base = &interpreter;
break;

case CoreMode::JIT: // Switching from interpreter to JIT.
// Don't really need to do much. It'll work, the cache will refill itself.
s_cpu_core_base = JitInterface::GetCore();
if (!s_cpu_core_base) // Has a chance to not get a working JIT core if one isn't active on host
s_cpu_core_base = s_interpreter;
s_cpu_core_base = &interpreter;
break;
}
}
Expand Down
9 changes: 8 additions & 1 deletion Source/Core/Core/System.cpp
Expand Up @@ -22,6 +22,7 @@
#include "Core/HW/SI/SI.h"
#include "Core/HW/Sram.h"
#include "Core/HW/VideoInterface.h"
#include "Core/PowerPC/Interpreter/Interpreter.h"
#include "Core/PowerPC/PowerPC.h"
#include "IOS/USB/Emulated/Skylander.h"
#include "VideoCommon/CommandProcessor.h"
Expand All @@ -39,7 +40,7 @@ struct System::Impl
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system), m_memory(system),
m_ppc_state(PowerPC::ppcState), m_processor_interface(system), m_serial_interface(system),
m_video_interface(system)
m_video_interface(system), m_interpreter(system, m_ppc_state)
{
}

Expand Down Expand Up @@ -70,6 +71,7 @@ struct System::Impl
Sram m_sram;
VertexShaderManager m_vertex_shader_manager;
VideoInterface::VideoInterfaceManager m_video_interface;
Interpreter m_interpreter;
};

System::System() : m_impl{std::make_unique<Impl>(*this)}
Expand Down Expand Up @@ -175,6 +177,11 @@ HSP::HSPManager& System::GetHSP() const
return m_impl->m_hsp;
}

Interpreter& System::GetInterpreter() const
{
return m_impl->m_interpreter;
}

IOS::HLE::USB::SkylanderPortal& System::GetSkylanderPortal() const
{
return m_impl->m_skylander_portal;
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/System.h
Expand Up @@ -6,6 +6,7 @@
#include <memory>

class GeometryShaderManager;
class Interpreter;
class PixelShaderManager;
class SoundStream;
struct Sram;
Expand Down Expand Up @@ -131,6 +132,7 @@ class System
GeometryShaderManager& GetGeometryShaderManager() const;
GPFifo::GPFifoManager& GetGPFifo() const;
HSP::HSPManager& GetHSP() const;
Interpreter& GetInterpreter() const;
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
Memory::MemoryManager& GetMemory() const;
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
Expand Down