📄 altivec.igen
字号:
# Altivec instruction set, for PSIM, the PowerPC simulator.# Copyright 2003 Free Software Foundation, Inc.# Contributed by Red Hat Inc; developed under contract from Motorola.# Written by matthew green <mrg@redhat.com>.# This file is part of GDB.# 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. */## Motorola AltiVec instructions.#:cache:av:::VS:VS::cache:av::vreg *:vS:VS:(cpu_registers(processor)->altivec.vr + VS):cache:av::unsigned32:VS_BITMASK:VS:(1 << VS):cache:av:::VA:VA::cache:av::vreg *:vA:VA:(cpu_registers(processor)->altivec.vr + VA):cache:av::unsigned32:VA_BITMASK:VA:(1 << VA):cache:av:::VB:VB::cache:av::vreg *:vB:VB:(cpu_registers(processor)->altivec.vr + VB):cache:av::unsigned32:VB_BITMASK:VB:(1 << VB):cache:av:::VC:VC::cache:av::vreg *:vC:VC:(cpu_registers(processor)->altivec.vr + VC):cache:av::unsigned32:VC_BITMASK:VC:(1 << VC)# Flags for model.h::model-macro::: #define PPC_INSN_INT_VR(OUT_MASK, IN_MASK, OUT_VMASK, IN_VMASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_int_vr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, OUT_VMASK, IN_VMASK); \ } while (0) #define PPC_INSN_VR(OUT_VMASK, IN_VMASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_vr(MY_INDEX, cpu_model(processor), OUT_VMASK, IN_VMASK); \ } while (0) #define PPC_INSN_VR_CR(OUT_VMASK, IN_VMASK, CR_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_vr_cr(MY_INDEX, cpu_model(processor), OUT_VMASK, IN_VMASK, CR_MASK); \ } while (0) #define PPC_INSN_VR_VSCR(OUT_VMASK, IN_VMASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_vr_vscr(MY_INDEX, cpu_model(processor), OUT_VMASK, IN_VMASK); \ } while (0) #define PPC_INSN_FROM_VSCR(VR_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_from_vscr(MY_INDEX, cpu_model(processor), VR_MASK); \ } while (0) #define PPC_INSN_TO_VSCR(VR_MASK) \ do { \ if (CURRENT_MODEL_ISSUE > 0) \ ppc_insn_to_vscr(MY_INDEX, cpu_model(processor), VR_MASK); \ } while (0)# Trace waiting for AltiVec registers to become availablevoid::model-static::model_trace_altivec_busy_p:model_data *model_ptr, unsigned32 vr_busy int i; if (vr_busy) { vr_busy &= model_ptr->vr_busy; for(i = 0; i < 32; i++) { if (((1 << i) & vr_busy) != 0) { TRACE(trace_model, ("Waiting for register v%d.\n", i)); } } } if (model_ptr->vscr_busy) TRACE(trace_model, ("Waiting for VSCR\n"));# Trace making AltiVec registers busyvoid::model-static::model_trace_altivec_make_busy:model_data *model_ptr, unsigned32 vr_mask, unsigned32 cr_mask int i; if (vr_mask) { for(i = 0; i < 32; i++) { if (((1 << i) & vr_mask) != 0) { TRACE(trace_model, ("Register v%d is now busy.\n", i)); } } } if (cr_mask) { for(i = 0; i < 8; i++) { if (((1 << i) & cr_mask) != 0) { TRACE(trace_model, ("Register cr%d is now busy.\n", i)); } } }# Schedule an AltiVec instruction that takes integer input registers and produces output registersvoid::model-function::ppc_insn_int_vr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 out_vmask, const unsigned32 in_vmask const unsigned32 int_mask = out_mask | in_mask; const unsigned32 vr_mask = out_vmask | in_vmask; model_busy *busy_ptr; if ((model_ptr->int_busy & int_mask) != 0 || (model_ptr->vr_busy & vr_mask)) { model_new_cycle(model_ptr); /* don't count first dependency as a stall */ while ((model_ptr->int_busy & int_mask) != 0 || (model_ptr->vr_busy & vr_mask)) { if (WITH_TRACE && ppc_trace[trace_model]) { model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR); model_trace_altivec_busy_p(model_ptr, vr_mask); } model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->int_busy |= out_mask; busy_ptr->int_busy |= out_mask; model_ptr->vr_busy |= out_vmask; busy_ptr->vr_busy |= out_vmask; if (out_mask) busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_vmask)) ? 1 : 2; if (out_vmask) busy_ptr->nr_writebacks += (PPC_ONE_BIT_SET_P(out_vmask)) ? 1 : 2; if (WITH_TRACE && ppc_trace[trace_model]) { model_trace_make_busy(model_ptr, out_mask, 0, 0); model_trace_altivec_make_busy(model_ptr, vr_mask, 0); }# Schedule an AltiVec instruction that takes vector input registers and produces vector output registersvoid::model-function::ppc_insn_vr:itable_index index, model_data *model_ptr, const unsigned32 out_vmask, const unsigned32 in_vmask const unsigned32 vr_mask = out_vmask | in_vmask; model_busy *busy_ptr; if (model_ptr->vr_busy & vr_mask) { model_new_cycle(model_ptr); /* don't count first dependency as a stall */ while (model_ptr->vr_busy & vr_mask) { if (WITH_TRACE && ppc_trace[trace_model]) { model_trace_altivec_busy_p(model_ptr, vr_mask); } model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->vr_busy |= out_vmask; busy_ptr->vr_busy |= out_vmask; if (out_vmask) busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_vmask)) ? 1 : 2; if (WITH_TRACE && ppc_trace[trace_model]) { model_trace_altivec_make_busy(model_ptr, vr_mask, 0); }# Schedule an AltiVec instruction that takes vector input registers and produces vector output registers, touches CRvoid::model-function::ppc_insn_vr_cr:itable_index index, model_data *model_ptr, const unsigned32 out_vmask, const unsigned32 in_vmask, const unsigned32 cr_mask const unsigned32 vr_mask = out_vmask | in_vmask; model_busy *busy_ptr; if ((model_ptr->vr_busy & vr_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) { model_new_cycle(model_ptr); /* don't count first dependency as a stall */ while ((model_ptr->vr_busy & vr_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) { if (WITH_TRACE && ppc_trace[trace_model]) { model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR); model_trace_altivec_busy_p(model_ptr, vr_mask); } model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->cr_fpscr_busy |= cr_mask; busy_ptr->cr_fpscr_busy |= cr_mask; model_ptr->vr_busy |= out_vmask; busy_ptr->vr_busy |= out_vmask; if (out_vmask) busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_vmask)) ? 1 : 2; if (cr_mask) busy_ptr->nr_writebacks++; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_altivec_make_busy(model_ptr, vr_mask, cr_mask);# Schedule an AltiVec instruction that takes vector input registers and produces vector output registers, touches VSCRvoid::model-function::ppc_insn_vr_vscr:itable_index index, model_data *model_ptr, const unsigned32 out_vmask, const unsigned32 in_vmask const unsigned32 vr_mask = out_vmask | in_vmask; model_busy *busy_ptr; if ((model_ptr->vr_busy & vr_mask) != 0 || model_ptr->vscr_busy != 0) { model_new_cycle(model_ptr); /* don't count first dependency as a stall */ while ((model_ptr->vr_busy & vr_mask) != 0 || model_ptr->vscr_busy != 0) { if (WITH_TRACE && ppc_trace[trace_model]) model_trace_altivec_busy_p(model_ptr, vr_mask); model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->vr_busy |= out_vmask; busy_ptr->vr_busy |= out_vmask; model_ptr->vscr_busy = 1; busy_ptr->vscr_busy = 1; if (out_vmask) busy_ptr->nr_writebacks = 1 + (PPC_ONE_BIT_SET_P(out_vmask)) ? 1 : 2; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_altivec_make_busy(model_ptr, vr_mask, 0);# Schedule an MFVSCR instruction that VSCR input register and produces an AltiVec output registervoid::model-function::ppc_insn_from_vscr:itable_index index, model_data *model_ptr, const unsigned32 vr_mask model_busy *busy_ptr; while ((model_ptr->vr_busy & vr_mask) != 0 || model_ptr->vscr_busy != 0) { if (WITH_TRACE && ppc_trace[trace_model]) model_trace_altivec_busy_p(model_ptr, vr_mask); model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); model_ptr->cr_fpscr_busy |= vr_mask; busy_ptr->cr_fpscr_busy |= vr_mask; if (vr_mask) busy_ptr->nr_writebacks = 1; model_ptr->vr_busy |= vr_mask; if (WITH_TRACE && ppc_trace[trace_model]) model_trace_altivec_make_busy(model_ptr, vr_mask, 0);# Schedule an MTVSCR instruction that one AltiVec input register and produces a vscr output registervoid::model-function::ppc_insn_to_vscr:itable_index index, model_data *model_ptr, const unsigned32 vr_mask model_busy *busy_ptr; while ((model_ptr->vr_busy & vr_mask) != 0 || model_ptr->vscr_busy != 0) { if (WITH_TRACE && ppc_trace[trace_model]) model_trace_altivec_busy_p(model_ptr, vr_mask); model_ptr->nr_stalls_data++; model_new_cycle(model_ptr); } busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]); busy_ptr ->vscr_busy = 1; model_ptr->vscr_busy = 1; busy_ptr->nr_writebacks = 1; TRACE(trace_model,("Making VSCR busy.\n"));# The follow are AltiVec saturate operationssigned8::model-function::altivec_signed_saturate_8:signed16 val, int *sat signed8 rv; if (val > 127) { rv = 127; *sat = 1; } else if (val < -128) { rv = -128; *sat = 1; } else { rv = val; *sat = 0; } return rv;signed16::model-function::altivec_signed_saturate_16:signed32 val, int *sat signed16 rv; if (val > 32767) { rv = 32767; *sat = 1; } else if (val < -32768) { rv = -32768; *sat = 1; } else { rv = val; *sat = 0; } return rv;signed32::model-function::altivec_signed_saturate_32:signed64 val, int *sat signed32 rv; if (val > 2147483647) { rv = 2147483647; *sat = 1; } else if (val < -2147483648LL) { rv = -2147483648LL; *sat = 1; } else { rv = val; *sat = 0; } return rv;unsigned8::model-function::altivec_unsigned_saturate_8:signed16 val, int *sat unsigned8 rv; if (val > 255) { rv = 255; *sat = 1; } else if (val < 0) { rv = 0; *sat = 1; } else { rv = val; *sat = 0; } return rv;unsigned16::model-function::altivec_unsigned_saturate_16:signed32 val, int *sat unsigned16 rv; if (val > 65535) { rv = 65535; *sat = 1; } else if (val < 0) { rv = 0; *sat = 1; } else { rv = val; *sat = 0; } return rv;unsigned32::model-function::altivec_unsigned_saturate_32:signed64 val, int *sat unsigned32 rv; if (val > 4294967295LL) { rv = 4294967295LL; *sat = 1; } else if (val < 0) { rv = 0; *sat = 1; } else { rv = val; *sat = 0; } return rv;## Load instructions, 6-14 ... 6-22.#0.31,6.VS,11.RA,16.RB,21.7,31.0:X:av:lvebx %VD, %RA, %RB:Load Vector Element Byte Indexed unsigned_word b; unsigned_word EA; unsigned_word eb; if (RA_is_0) b = 0; else b = *rA; EA = b + *rB; eb = EA & 0xf; (*vS).b[AV_BINDEX(eb)] = MEM(unsigned, EA, 1); PPC_INSN_INT_VR(0, RA_BITMASK | RB_BITMASK, VS_BITMASK, 0);0.31,6.VS,11.RA,16.RB,21.39,31.0:X:av:lvehx %VD, %RA, %RB:Load Vector Element Half Word Indexed unsigned_word b; unsigned_word EA; unsigned_word eb; if (RA_is_0) b = 0; else b = *rA; EA = (b + *rB) & ~1; eb = EA & 0xf; (*vS).h[AV_HINDEX(eb/2)] = MEM(unsigned, EA, 2); PPC_INSN_INT_VR(0, RA_BITMASK | RB_BITMASK, VS_BITMASK, 0);0.31,6.VS,11.RA,16.RB,21.71,31.0:X:av:lvewx %VD, %RA, %RB:Load Vector Element Word Indexed unsigned_word b; unsigned_word EA; unsigned_word eb; if (RA_is_0) b = 0; else b = *rA; EA = (b + *rB) & ~3; eb = EA & 0xf; (*vS).w[eb/4] = MEM(unsigned, EA, 4); PPC_INSN_INT_VR(0, RA_BITMASK | RB_BITMASK, VS_BITMASK, 0);0.31,6.VS,11.RA,16.RB,21.6,31.0:X:av:lvsl %VD, %RA, %RB:Load Vector for Shift Left unsigned_word b; unsigned_word addr; int i, j; if (RA_is_0) b = 0; else b = *rA; addr = b + *rB; j = addr & 0xf; for (i = 0; i < 16; i++) if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) (*vS).b[AV_BINDEX(i)] = j++; else (*vS).b[AV_BINDEX(15 - i)] = j++; PPC_INSN_INT_VR(0, RA_BITMASK | RB_BITMASK, VS_BITMASK, 0);0.31,6.VS,11.RA,16.RB,21.38,31.0:X:av:lvsr %VD, %RA, %RB:Load Vector for Shift Right unsigned_word b; unsigned_word addr; int i, j; if (RA_is_0) b = 0; else b = *rA; addr = b + *rB; j = 0x10 - (addr & 0xf); for (i = 0; i < 16; i++) if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) (*vS).b[AV_BINDEX(i)] = j++; else (*vS).b[AV_BINDEX(15 - i)] = j++; PPC_INSN_INT_VR(0, RA_BITMASK | RB_BITMASK, VS_BITMASK, 0);0.31,6.VS,11.RA,16.RB,21.103,31.0:X:av:lvx %VD, %RA, %RB:Load Vector Indexed unsigned_word b; unsigned_word EA; if (RA_is_0) b = 0; else b = *rA; EA = (b + *rB) & ~0xf; if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) { (*vS).w[0] = MEM(unsigned, EA + 0, 4); (*vS).w[1] = MEM(unsigned, EA + 4, 4); (*vS).w[2] = MEM(unsigned, EA + 8, 4); (*vS).w[3] = MEM(unsigned, EA + 12, 4); } else { (*vS).w[0] = MEM(unsigned, EA + 12, 4); (*vS).w[1] = MEM(unsigned, EA + 8, 4); (*vS).w[2] = MEM(unsigned, EA + 4, 4); (*vS).w[3] = MEM(unsigned, EA + 0, 4); } PPC_INSN_INT_VR(0, RA_BITMASK | RB_BITMASK, VS_BITMASK, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -