mirror of
https://github.com/Lime3DS/Lime3DS
synced 2024-12-26 17:12:37 -06:00
VFP: Minor cleanup, functionally the same.
This commit is contained in:
parent
dd21f986b8
commit
b11518c272
1 changed files with 2446 additions and 2557 deletions
|
@ -1,22 +1,6 @@
|
||||||
/*
|
// Copyright 2012 Michael Kang, 2015 Citra Emulator Project
|
||||||
vfp/vfpinstr.c - ARM VFPv3 emulation unit - Individual instructions data
|
// Licensed under GPLv2 or any later version
|
||||||
Copyright (C) 2003 Skyeye Develop Group
|
// Refer to the license.txt file included.
|
||||||
for help please send mail to <skyeye-developer@lists.gro.clinux.org>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Notice: this file should not be compiled as is, and is meant to be
|
/* Notice: this file should not be compiled as is, and is meant to be
|
||||||
included in other files only. */
|
included in other files only. */
|
||||||
|
@ -1227,7 +1211,6 @@ typedef struct _vmovr_inst {
|
||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
|
ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
|
||||||
{
|
{
|
||||||
VFP_DEBUG_TRANSLATE;
|
VFP_DEBUG_TRANSLATE;
|
||||||
VFP_DEBUG_UNTESTED(VMOVR);
|
|
||||||
|
|
||||||
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
|
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
|
||||||
vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
|
vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
|
||||||
|
@ -1308,8 +1291,6 @@ typedef struct _vabs_inst {
|
||||||
#ifdef VFP_INTERPRETER_TRANS
|
#ifdef VFP_INTERPRETER_TRANS
|
||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
|
ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
|
||||||
{
|
{
|
||||||
VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS);
|
|
||||||
|
|
||||||
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
|
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
|
||||||
vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
|
vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
|
||||||
|
|
||||||
|
@ -1416,8 +1397,6 @@ typedef struct _vneg_inst {
|
||||||
#ifdef VFP_INTERPRETER_TRANS
|
#ifdef VFP_INTERPRETER_TRANS
|
||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
|
ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
|
||||||
{
|
{
|
||||||
VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG);
|
|
||||||
|
|
||||||
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
|
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
|
||||||
vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
|
vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
|
||||||
|
|
||||||
|
@ -2942,29 +2921,14 @@ int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
// bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap);
|
// bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap);
|
||||||
//Value* phys_addr;
|
//Value* phys_addr;
|
||||||
if(single){
|
if(single){
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR(d), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, Addr, RSPR(d), 32);
|
//memory_write(cpu, bb, Addr, RSPR(d), 32);
|
||||||
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32);
|
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
|
//memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
|
||||||
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
|
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2 + 1), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
|
//memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
|
||||||
memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
|
memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
|
@ -3074,11 +3038,6 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
if (single)
|
if (single)
|
||||||
{
|
{
|
||||||
//Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
|
//Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, Addr, RSPR(d + i), 32);
|
//memory_write(cpu, bb, Addr, RSPR(d + i), 32);
|
||||||
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32);
|
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
|
@ -3087,19 +3046,9 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Careful of endianness, little by default */
|
/* Careful of endianness, little by default */
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
|
//memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
|
||||||
memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32);
|
memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
|
//memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
|
||||||
memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
|
memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
|
@ -3236,11 +3185,6 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
|
|
||||||
//Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
|
//Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
|
||||||
/* if R(i) is R15? */
|
/* if R(i) is R15? */
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, Addr, RSPR(d + i), 32);
|
//memory_write(cpu, bb, Addr, RSPR(d + i), 32);
|
||||||
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32);
|
memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
|
@ -3251,21 +3195,11 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
{
|
{
|
||||||
|
|
||||||
//Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
|
//Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
|
//memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
|
||||||
memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32);
|
memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
|
|
||||||
//Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
|
//Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
|
|
||||||
#endif
|
|
||||||
//memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
|
//memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
|
||||||
memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
|
memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
|
@ -3399,11 +3333,6 @@ int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
{
|
{
|
||||||
if (single)
|
if (single)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
|
@ -3413,20 +3342,10 @@ int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Careful of endianness, little by default */
|
/* Careful of endianness, little by default */
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
LETFPS((d + i) * 2, FPBITCAST32(val));
|
LETFPS((d + i) * 2, FPBITCAST32(val));
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
|
memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
|
@ -3547,11 +3466,6 @@ int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
//Value* phys_addr;
|
//Value* phys_addr;
|
||||||
Value* val;
|
Value* val;
|
||||||
if(single){
|
if(single){
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
|
@ -3559,21 +3473,11 @@ int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
LETFPS(d,FPBITCAST32(val));
|
LETFPS(d,FPBITCAST32(val));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
//LETS(d * 2, val);
|
//LETS(d * 2, val);
|
||||||
LETFPS(d * 2,FPBITCAST32(val));
|
LETFPS(d * 2,FPBITCAST32(val));
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
|
memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
|
@ -3708,11 +3612,6 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
|
|
||||||
//Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
|
//Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
|
||||||
/* if R(i) is R15? */
|
/* if R(i) is R15? */
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
|
@ -3723,20 +3622,10 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, Addr, 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
LETFPS((d + i) * 2, FPBITCAST32(val));
|
LETFPS((d + i) * 2, FPBITCAST32(val));
|
||||||
#if 0
|
|
||||||
phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
|
|
||||||
bb = cpu->dyncom_engine->bb;
|
|
||||||
val = arch_read_memory(cpu,bb,phys_addr,0,32);
|
|
||||||
#endif
|
|
||||||
memory_read(cpu, bb, Addr, 0, 32);
|
memory_read(cpu, bb, Addr, 0, 32);
|
||||||
bb = cpu->dyncom_engine->bb;
|
bb = cpu->dyncom_engine->bb;
|
||||||
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
|
||||||
|
|
Loading…
Reference in a new issue