1 /* Copyright (C) 1998, Cygnus Solutions */
9 #include "sim-assert.h"
12 #include "sky-gpuif.h"
15 /* Imported functions */
17 void device_error (device
*me
, char* message
); /* device.c */
20 /* Internal function declarations */
22 static int pke_io_read_buffer(device
*, void*, int, address_word
,
23 unsigned, sim_cpu
*, sim_cia
);
24 static int pke_io_write_buffer(device
*, const void*, int, address_word
,
25 unsigned, sim_cpu
*, sim_cia
);
26 static void pke_issue(struct pke_device
*);
27 static void pke_pc_advance(struct pke_device
*, int num_words
);
28 static unsigned_4
* pke_pc_operand(struct pke_device
*, int operand_num
);
29 static struct fifo_quadword
* pke_pc_fifo(struct pke_device
*, int operand_num
,
30 unsigned_4
** operand
);
31 static int pke_track_write(struct pke_device
*, const void* src
, int len
,
32 address_word dest
, unsigned_4 sourceaddr
);
33 static void pke_attach(SIM_DESC sd
, struct pke_device
* me
);
34 enum pke_check_target
{ chk_vu
, chk_path1
, chk_path2
, chk_path3
};
35 static int pke_check_stall(struct pke_device
* me
, enum pke_check_target what
);
36 static void pke_flip_dbf(struct pke_device
* me
);
37 /* PKEcode handlers */
38 static void pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
);
39 static void pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
);
40 static void pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
);
41 static void pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
);
42 static void pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
);
43 static void pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
);
44 static void pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
);
45 static void pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
);
46 static void pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
);
47 static void pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
);
48 static void pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
);
49 static void pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
);
50 static void pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
);
51 static void pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
);
52 static void pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
);
53 static void pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
);
54 static void pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
);
55 static void pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
);
56 static void pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
);
57 static void pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
);
58 static void pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
);
59 static void pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
);
65 struct pke_device pke0_device
=
67 { "pke0", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
70 NULL
, 0, 0, NULL
, /* FIFO */
75 struct pke_device pke1_device
=
77 { "pke1", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
80 NULL
, 0, 0, NULL
, /* FIFO */
86 /* External functions */
89 /* Attach PKE addresses to main memory */
92 pke0_attach(SIM_DESC sd
)
94 pke_attach(sd
, & pke0_device
);
98 pke1_attach(SIM_DESC sd
)
100 pke_attach(sd
, & pke1_device
);
105 /* Issue a PKE instruction if possible */
110 pke_issue(& pke0_device
);
116 pke_issue(& pke0_device
);
121 /* Internal functions */
124 /* Attach PKE memory regions to simulator */
127 pke_attach(SIM_DESC sd
, struct pke_device
* me
)
135 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
,
136 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
138 (device
*) &pke0_device
,
147 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
,
148 sizeof(quadword
) /*nr_bytes*/,
150 (device
*) &pke1_device
,
153 /* source-addr tracking word */
159 (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
160 sizeof(unsigned_4
) /*nr_bytes*/,
163 zalloc(sizeof(unsigned_4
)) /*buffer*/);
168 /* Handle a PKE read; return no. of bytes read */
171 pke_io_read_buffer(device
*me_
,
179 /* downcast to gather embedding pke_device struct */
180 struct pke_device
* me
= (struct pke_device
*) me_
;
182 /* find my address ranges */
183 address_word my_reg_start
=
184 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
185 address_word my_fifo_addr
=
186 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
188 /* enforce that an access does not span more than one quadword */
189 address_word low
= ADDR_TRUNC_QW(addr
);
190 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
194 /* classify address & handle */
195 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
198 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
199 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
204 result
[0] = result
[1] = result
[2] = result
[3] = 0;
206 /* handle reads to individual registers; clear `readable' on error */
209 /* handle common case of register reading, side-effect free */
210 /* PKE1-only registers*/
216 if(me
->pke_number
== 0)
219 /* PKE0 & PKE1 common registers*/
238 result
[0] = me
->regs
[reg_num
][0];
241 /* handle common case of write-only registers */
247 ASSERT(0); /* test above should prevent this possibility */
250 /* perform transfer & return */
254 memcpy(dest
, ((unsigned_1
*) &result
) + reg_byte
, nr_bytes
);
266 else if(addr
>= my_fifo_addr
&&
267 addr
< my_fifo_addr
+ sizeof(quadword
))
271 /* FIFO is not readable: return a word of zeroes */
272 memset(dest
, 0, nr_bytes
);
281 /* Handle a PKE read; return no. of bytes written */
284 pke_io_write_buffer(device
*me_
,
292 /* downcast to gather embedding pke_device struct */
293 struct pke_device
* me
= (struct pke_device
*) me_
;
295 /* find my address ranges */
296 address_word my_reg_start
=
297 (me
->pke_number
== 0) ? PKE0_REGISTER_WINDOW_START
: PKE1_REGISTER_WINDOW_START
;
298 address_word my_fifo_addr
=
299 (me
->pke_number
== 0) ? PKE0_FIFO_ADDR
: PKE1_FIFO_ADDR
;
301 /* enforce that an access does not span more than one quadword */
302 address_word low
= ADDR_TRUNC_QW(addr
);
303 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
307 /* classify address & handle */
308 if((addr
>= my_reg_start
) && (addr
< my_reg_start
+ PKE_REGISTER_WINDOW_SIZE
))
311 int reg_num
= ADDR_TRUNC_QW(addr
- my_reg_start
) >> 4;
312 int reg_byte
= ADDR_OFFSET_QW(addr
); /* find byte-offset inside register bank */
317 input
[0] = input
[1] = input
[2] = input
[3] = 0;
319 /* write user-given bytes into input */
320 memcpy(((unsigned_1
*) &input
) + reg_byte
, src
, nr_bytes
);
322 /* handle writes to individual registers; clear `writeable' on error */
326 /* Order these tests from least to most overriding, in case
327 multiple bits are set. */
328 if(BIT_MASK_GET(input
[0], 2, 2)) /* STC bit */
330 /* clear a bunch of status bits */
331 PKE_REG_MASK_SET(me
, STAT
, PSS
, 0);
332 PKE_REG_MASK_SET(me
, STAT
, PFS
, 0);
333 PKE_REG_MASK_SET(me
, STAT
, PIS
, 0);
334 PKE_REG_MASK_SET(me
, STAT
, INT
, 0);
335 PKE_REG_MASK_SET(me
, STAT
, ER0
, 0);
336 PKE_REG_MASK_SET(me
, STAT
, ER1
, 0);
337 /* will allow resumption of possible stalled instruction */
339 if(BIT_MASK_GET(input
[0], 2, 2)) /* STP bit */
341 /* XXX: how to safely abort "currently executing" (=> stalled) instruction? */
342 PKE_REG_MASK_SET(me
, STAT
, PSS
, 1);
344 if(BIT_MASK_GET(input
[0], 1, 1)) /* FBK bit */
346 PKE_REG_MASK_SET(me
, STAT
, PFS
, 1);
348 if(BIT_MASK_GET(input
[0], 0, 0)) /* RST bit */
350 /* clear FIFO by skipping to word after PC: also
351 prevents re-execution attempt of possible stalled
353 me
->fifo_num_elements
= me
->fifo_pc
;
354 /* clear registers */
355 memset(me
->regs
, 0, sizeof(me
->regs
));
362 /* copy bottom three bits */
363 BIT_MASK_SET(me
->regs
[PKE_REG_ERR
][0], 0, 2, BIT_MASK_GET(input
[0], 0, 2));
367 /* copy bottom sixteen bits */
368 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(input
[0], 0, 15));
369 /* reset MRK bit in STAT */
370 PKE_REG_MASK_SET(me
, STAT
, MRK
, 0);
373 /* handle common case of read-only registers */
374 /* PKE1-only registers - not really necessary to handle separately */
380 if(me
->pke_number
== 0)
383 /* PKE0 & PKE1 common registers*/
385 /* ignore FDR bit for PKE1_STAT -- simulator does not implement PKE->RAM transfers */
405 ASSERT(0); /* test above should prevent this possibility */
422 else if(addr
>= my_fifo_addr
&&
423 addr
< my_fifo_addr
+ sizeof(quadword
))
426 struct fifo_quadword
* fqw
;
428 /* assert transfer size == 128 bits */
429 if(nr_bytes
!= sizeof(quadword
))
432 /* ensure FIFO has enough elements */
433 if(me
->fifo_num_elements
== me
->fifo_buffer_size
)
436 int new_fifo_buffer_size
= me
->fifo_buffer_size
+ 20;
437 void* ptr
= realloc((void*) me
->fifo
, new_fifo_buffer_size
*sizeof(quadword
));
441 /* oops, cannot enlarge FIFO any more */
442 device_error(me_
, "Cannot enlarge FIFO buffer\n");
446 me
->fifo_buffer_size
= new_fifo_buffer_size
;
449 /* add new quadword at end of FIFO */
450 fqw
= & me
->fifo
[me
->fifo_num_elements
];
451 memcpy((void*) fqw
->data
, src
, nr_bytes
);
452 sim_read(CPU_STATE(cpu
),
453 (SIM_ADDR
) (me
->pke_number
== 0 ? DMA_D0_SRCADDR
: DMA_D1_SRCADDR
),
454 (void*) & fqw
->source_address
,
455 sizeof(address_word
));
456 sim_read(CPU_STATE(cpu
),
457 (SIM_ADDR
) (me
->pke_number
== 0 ? DMA_D0_PKTFLAG
: DMA_D1_PKTFLAG
),
458 (void*) & fqw
->dma_tag_present
,
461 me
->fifo_num_elements
++;
463 /* set FQC to "1" as FIFO is now not empty */
464 PKE_REG_MASK_SET(me
, STAT
, FQC
, 1);
476 /* Issue & swallow next PKE opcode if possible/available */
479 pke_issue(struct pke_device
* me
)
481 struct fifo_quadword
* fqw
;
483 unsigned_4 cmd
, intr
, num
;
486 /* 1 -- test go / no-go for PKE execution */
488 /* check for stall/halt control bits */
489 if(PKE_REG_MASK_GET(me
, STAT
, PSS
) || /* XXX: PSS may be a special case */
490 PKE_REG_MASK_GET(me
, STAT
, PFS
) ||
491 /* PEW bit not a reason to keep stalling - it's re-checked below */
492 /* PGW bit not a reason to keep stalling - it's re-checked below */
493 /* maskable stall controls: ER0, ER1, PIS */
494 (PKE_REG_MASK_GET(me
, STAT
, ER0
) && !PKE_REG_MASK_GET(me
, ERR
, ME0
)) ||
495 (PKE_REG_MASK_GET(me
, STAT
, ER1
) && !PKE_REG_MASK_GET(me
, ERR
, ME1
)) ||
496 (PKE_REG_MASK_GET(me
, STAT
, PIS
) && !PKE_REG_MASK_GET(me
, ERR
, MII
)))
498 /* try again next cycle; no state change */
501 /* XXX: handle PSS by *skipping* instruction? */
503 /* confirm availability of new quadword of PKE instructions */
504 if(me
->fifo_num_elements
<= me
->fifo_pc
)
508 /* 2 -- fetch PKE instruction */
510 /* skip over DMA tag, if present */
511 pke_pc_advance(me
, 0);
513 /* "fetch" instruction quadword and word */
514 fqw
= & me
->fifo
[me
->fifo_pc
];
515 fw
= fqw
->data
[me
->qw_pc
];
517 /* store word in PKECODE register */
518 me
->regs
[PKE_REG_CODE
][0] = fw
;
521 /* 3 -- decode PKE instruction */
523 /* PKE instruction format: [intr 0:0][pke-command 6:0][num 7:0][immediate 15:0],
524 so op-code is in top byte. */
525 intr
= BIT_MASK_GET(fw
, PKE_OPCODE_I_B
, PKE_OPCODE_I_E
);
526 cmd
= BIT_MASK_GET(fw
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
527 num
= BIT_MASK_GET(fw
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
528 imm
= BIT_MASK_GET(fw
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
532 /* set INT flag in STAT register */
533 PKE_REG_MASK_SET(me
, STAT
, INT
, 1);
534 /* XXX: send interrupt to R5900? */
538 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_DECODE
);
540 /* decode & execute */
541 if(IS_PKE_CMD(cmd
, PKENOP
))
542 pke_code_nop(me
, fw
);
543 else if(IS_PKE_CMD(cmd
, STCYCL
))
544 pke_code_stcycl(me
, fw
);
545 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, OFFSET
))
546 pke_code_offset(me
, fw
);
547 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, BASE
))
548 pke_code_base(me
, fw
);
549 else if(IS_PKE_CMD(cmd
, ITOP
))
550 pke_code_itop(me
, fw
);
551 else if(IS_PKE_CMD(cmd
, STMOD
))
552 pke_code_stmod(me
, fw
);
553 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, MSKPATH3
))
554 pke_code_mskpath3(me
, fw
);
555 else if(IS_PKE_CMD(cmd
, PKEMARK
))
556 pke_code_pkemark(me
, fw
);
557 else if(IS_PKE_CMD(cmd
, FLUSHE
))
558 pke_code_flushe(me
, fw
);
559 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSH
))
560 pke_code_flush(me
, fw
);
561 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, FLUSHA
))
562 pke_code_flusha(me
, fw
);
563 else if(IS_PKE_CMD(cmd
, PKEMSCAL
))
564 pke_code_pkemscal(me
, fw
);
565 else if(IS_PKE_CMD(cmd
, PKEMSCNT
))
566 pke_code_pkemscnt(me
, fw
);
567 else if(me
->pke_number
== 1 && IS_PKE_CMD(cmd
, PKEMSCALF
))
568 pke_code_pkemscalf(me
, fw
);
569 else if(IS_PKE_CMD(cmd
, STMASK
))
570 pke_code_stmask(me
, fw
);
571 else if(IS_PKE_CMD(cmd
, STROW
))
572 pke_code_strow(me
, fw
);
573 else if(IS_PKE_CMD(cmd
, STCOL
))
574 pke_code_stcol(me
, fw
);
575 else if(IS_PKE_CMD(cmd
, MPG
))
576 pke_code_mpg(me
, fw
);
577 else if(IS_PKE_CMD(cmd
, DIRECT
))
578 pke_code_direct(me
, fw
);
579 else if(IS_PKE_CMD(cmd
, DIRECTHL
))
580 pke_code_directhl(me
, fw
);
581 else if(IS_PKE_CMD(cmd
, UNPACK
))
582 pke_code_unpack(me
, fw
);
583 /* ... other commands ... */
585 pke_code_error(me
, fw
);
590 /* advance the PC by given number of data words; update STAT/FQC
591 field; assume FIFO is filled enough */
594 pke_pc_advance(struct pke_device
* me
, int num_words
)
597 ASSERT(num_words
> 0);
601 struct fifo_quadword
* fq
;
603 /* one word skipped */
606 /* point to next word */
614 /* skip over DMA tag words if present in word 0 or 1 */
615 fq
= & me
->fifo
[me
->fifo_pc
];
616 if(fq
->dma_tag_present
&& (me
->qw_pc
< 2))
618 /* skip by going around loop an extra time */
623 /* clear FQC if FIFO is now empty */
624 if(me
->fifo_num_elements
== me
->fifo_pc
)
626 PKE_REG_MASK_SET(me
, STAT
, FQC
, 0);
632 /* Return pointer to FIFO quadword containing given operand# in FIFO.
633 `operand_num' starts at 1. Return pointer to operand word in last
634 argument, if non-NULL. If FIFO is not full enough, return 0.
635 Signal an ER0 indication upon skipping a DMA tag. */
637 struct fifo_quadword
*
638 pke_pc_fifo(struct pke_device
* me
, int operand_num
, unsigned_4
** operand
)
640 int num
= operand_num
;
641 int new_qw_pc
, new_fifo_pc
;
642 struct fifo_quadword
* operand_fifo
= NULL
;
646 /* snapshot current pointers */
647 new_fifo_pc
= me
->fifo_pc
;
648 new_qw_pc
= me
->qw_pc
;
652 /* one word skipped */
655 /* point to next word */
663 /* check for FIFO underflow */
664 if(me
->fifo_num_elements
== new_fifo_pc
)
670 /* skip over DMA tag words if present in word 0 or 1 */
671 operand_fifo
= & me
->fifo
[new_fifo_pc
];
672 if(operand_fifo
->dma_tag_present
&& (new_qw_pc
< 2))
674 /* mismatch error! */
675 PKE_REG_MASK_SET(me
, STAT
, ER0
, 1);
676 /* skip by going around loop an extra time */
681 /* return pointer to operand word itself */
682 if(operand_fifo
!= NULL
)
683 *operand
= & operand_fifo
->data
[new_qw_pc
];
689 /* Return pointer to given operand# in FIFO. `operand_num' starts at 1.
690 If FIFO is not full enough, return 0. Skip over DMA tags, but mark
691 them as an error (ER0). */
694 pke_pc_operand(struct pke_device
* me
, int operand_num
)
696 unsigned_4
* operand
= NULL
;
697 struct fifo_quadword
* fifo_operand
;
699 fifo_operand
= pke_pc_fifo(me
, operand_num
, & operand
);
701 if(fifo_operand
== NULL
)
702 ASSERT(operand
== NULL
); /* pke_pc_fifo() ought leave it untouched */
712 /* Write a bunch of bytes into simulator memory. Store the given source address into the
713 PKE sourceaddr tracking word. */
715 pke_track_write(struct pke_device
* me
, const void* src
, int len
,
716 address_word dest
, unsigned_4 sourceaddr
)
719 unsigned_4 no_sourceaddr
= 0;
721 /* write srcaddr into PKE srcaddr tracking */
723 (SIM_ADDR
) (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
724 (void*) & sourceaddr
,
727 /* write bytes into simulator */
733 /* clear srcaddr from PKE srcaddr tracking */
735 (SIM_ADDR
) (me
->pke_number
== 0) ? PKE0_SRCADDR
: PKE1_SRCADDR
,
736 (void*) & no_sourceaddr
,
743 /* check for stall conditions on indicated devices (path* only on PKE1), do not change status
744 return 0 iff no stall */
746 pke_check_stall(struct pke_device
* me
, enum pke_check_target what
)
750 /* read VU status word - commonly used */
753 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
760 /* check if VBS bit is set, i.e., VU is busy */
761 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 1)
764 else if(what
== chk_path1
)
766 /* only valid on PKE1 */
767 /* check if VGW bit is set, i.e., PATH1 is busy */
768 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VGW_B
, VU_REG_STAT_VGW_E
) == 1)
773 ASSERT(0); /* XXX: not done yet */
776 /* any stall reasons? */
781 /* flip the DBF bit; recompute TOPS, ITOP & TOP */
783 pke_flip_dbf(struct pke_device
* me
)
786 PKE_REG_MASK_SET(me
, DBF
, DF
,
787 PKE_REG_MASK_GET(me
, DBF
, DF
) ? 0 : 1);
788 PKE_REG_MASK_SET(me
, STAT
, DBF
, PKE_REG_MASK_GET(me
, DBF
, DF
));
789 /* compute new TOPS */
790 PKE_REG_MASK_SET(me
, TOPS
, TOPS
,
791 (PKE_REG_MASK_GET(me
, BASE
, BASE
) +
792 (PKE_REG_MASK_GET(me
, DBF
, DF
) *
793 PKE_REG_MASK_GET(me
, OFST
, OFFSET
))));
794 /* compute new ITOP and TOP */
795 PKE_REG_MASK_SET(me
, ITOP
, ITOP
,
796 PKE_REG_MASK_GET(me
, ITOPS
, ITOPS
));
797 PKE_REG_MASK_SET(me
, TOP
, TOP
,
798 PKE_REG_MASK_GET(me
, TOPS
, TOPS
));
803 /* PKEcode handler functions -- responsible for checking and
804 confirming old stall conditions, executing pkecode, updating PC and
805 status registers -- may assume being run on correct PKE unit */
808 pke_code_nop(struct pke_device
* me
, unsigned_4 pkecode
)
811 pke_pc_advance(me
, 1);
812 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
817 pke_code_stcycl(struct pke_device
* me
, unsigned_4 pkecode
)
819 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
820 /* copy immediate value into CYCLE reg */
821 me
->regs
[PKE_REG_CYCLE
][0] = imm
;
823 pke_pc_advance(me
, 1);
824 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
829 pke_code_offset(struct pke_device
* me
, unsigned_4 pkecode
)
831 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
832 /* copy 10 bits to OFFSET field */
833 PKE_REG_MASK_SET(me
, OFST
, OFFSET
, BIT_MASK_GET(imm
, 0, 9));
835 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
836 /* clear other DBF bit */
837 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
838 /* set TOPS = BASE */
839 PKE_REG_MASK_SET(me
, TOPS
, TOPS
, PKE_REG_MASK_GET(me
, BASE
, BASE
));
841 pke_pc_advance(me
, 1);
842 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
847 pke_code_base(struct pke_device
* me
, unsigned_4 pkecode
)
849 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
850 /* copy 10 bits to BASE field */
851 PKE_REG_MASK_SET(me
, BASE
, BASE
, BIT_MASK_GET(imm
, 0, 9));
853 PKE_REG_MASK_SET(me
, DBF
, DF
, 0);
854 /* clear other DBF bit */
855 PKE_REG_MASK_SET(me
, STAT
, DBF
, 0);
856 /* set TOPS = BASE */
857 PKE_REG_MASK_SET(me
, TOPS
, TOPS
, PKE_REG_MASK_GET(me
, BASE
, BASE
));
859 pke_pc_advance(me
, 1);
860 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
865 pke_code_itop(struct pke_device
* me
, unsigned_4 pkecode
)
867 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
868 /* copy 10 bits to ITOPS field */
869 PKE_REG_MASK_SET(me
, ITOPS
, ITOPS
, BIT_MASK_GET(imm
, 0, 9));
871 pke_pc_advance(me
, 1);
872 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
877 pke_code_stmod(struct pke_device
* me
, unsigned_4 pkecode
)
879 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
880 /* copy 2 bits to MODE register */
881 PKE_REG_MASK_SET(me
, MODE
, MDE
, BIT_MASK_GET(imm
, 0, 2));
883 pke_pc_advance(me
, 1);
884 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
889 pke_code_mskpath3(struct pke_device
* me
, unsigned_4 pkecode
)
892 /* XXX: cannot handle this one yet */
897 pke_code_pkemark(struct pke_device
* me
, unsigned_4 pkecode
)
899 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
900 /* copy 16 bits to MARK register */
901 PKE_REG_MASK_SET(me
, MARK
, MARK
, BIT_MASK_GET(imm
, 0, 15));
902 /* set MRK bit in STAT register - CPU2 v2.1 docs incorrect */
903 PKE_REG_MASK_SET(me
, STAT
, MRK
, 1);
905 pke_pc_advance(me
, 1);
906 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
911 pke_code_flushe(struct pke_device
* me
, unsigned_4 pkecode
)
913 /* compute next PEW bit */
914 if(pke_check_stall(me
, chk_vu
))
917 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
918 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
919 /* try again next cycle */
924 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
925 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
926 pke_pc_advance(me
, 1);
932 pke_code_flush(struct pke_device
* me
, unsigned_4 pkecode
)
934 int something_busy
= 0;
936 /* compute next PEW, PGW bits */
937 if(pke_check_stall(me
, chk_vu
))
940 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
943 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
946 if(pke_check_stall(me
, chk_path1
) ||
947 pke_check_stall(me
, chk_path2
))
950 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
953 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
958 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
959 /* try again next cycle */
964 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
965 pke_pc_advance(me
, 1);
971 pke_code_flusha(struct pke_device
* me
, unsigned_4 pkecode
)
973 int something_busy
= 0;
975 /* compute next PEW, PGW bits */
976 if(pke_check_stall(me
, chk_vu
))
979 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
982 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
985 if(pke_check_stall(me
, chk_path1
) ||
986 pke_check_stall(me
, chk_path2
) ||
987 pke_check_stall(me
, chk_path3
))
990 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
993 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
997 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
998 /* try again next cycle */
1003 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1004 pke_pc_advance(me
, 1);
1010 pke_code_pkemscal(struct pke_device
* me
, unsigned_4 pkecode
)
1012 /* compute next PEW bit */
1013 if(pke_check_stall(me
, chk_vu
))
1016 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1017 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1018 /* try again next cycle */
1023 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1026 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1028 /* flip DBF on PKE1 */
1029 if(me
->pke_number
== 1)
1032 /* compute new PC for VU */
1033 vu_pc
= BIT_MASK_GET(imm
, 0, 15); /* XXX: all bits significant? */
1034 /* write new PC; callback function gets VU running */
1036 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1038 sizeof(unsigned_4
));
1041 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1042 pke_pc_advance(me
, 1);
1049 pke_code_pkemscnt(struct pke_device
* me
, unsigned_4 pkecode
)
1051 /* compute next PEW bit */
1052 if(pke_check_stall(me
, chk_vu
))
1055 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1056 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1057 /* try again next cycle */
1064 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1066 /* flip DBF on PKE1 */
1067 if(me
->pke_number
== 1)
1072 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1074 sizeof(unsigned_4
));
1076 /* rewrite new PC; callback function gets VU running */
1078 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1080 sizeof(unsigned_4
));
1083 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1084 pke_pc_advance(me
, 1);
1090 pke_code_pkemscalf(struct pke_device
* me
, unsigned_4 pkecode
)
1092 int something_busy
= 0;
1094 /* compute next PEW, PGW bits */
1095 if(pke_check_stall(me
, chk_vu
))
1098 PKE_REG_MASK_SET(me
, STAT
, PEW
, 1);
1101 PKE_REG_MASK_SET(me
, STAT
, PEW
, 0);
1104 if(pke_check_stall(me
, chk_path1
) ||
1105 pke_check_stall(me
, chk_path2
) ||
1106 pke_check_stall(me
, chk_path3
))
1109 PKE_REG_MASK_SET(me
, STAT
, PGW
, 1);
1112 PKE_REG_MASK_SET(me
, STAT
, PGW
, 0);
1117 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1118 /* try again next cycle */
1123 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1125 /* flip DBF on PKE1 */
1126 if(me
->pke_number
== 1)
1129 /* compute new PC for VU */
1130 vu_pc
= BIT_MASK_GET(imm
, 0, 15); /* XXX: all bits significant? */
1131 /* write new PC; callback function gets VU running */
1133 (SIM_ADDR
) (me
->pke_number
== 0 ? VU0_PC_START
: VU1_PC_START
),
1135 sizeof(unsigned_4
));
1138 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1139 pke_pc_advance(me
, 1);
1145 pke_code_stmask(struct pke_device
* me
, unsigned_4 pkecode
)
1147 /* check that FIFO has one more word for STMASK operand */
1150 mask
= pke_pc_operand(me
, 1);
1153 /* "transferring" operand */
1154 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1155 /* fill the register */
1156 PKE_REG_MASK_SET(me
, MASK
, MASK
, *mask
);
1158 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1159 pke_pc_advance(me
, 1);
1163 /* need to wait for another word */
1164 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1165 /* try again next cycle */
1171 pke_code_strow(struct pke_device
* me
, unsigned_4 pkecode
)
1173 /* check that FIFO has four more words for STROW operand */
1174 unsigned_4
* last_op
;
1176 last_op
= pke_pc_operand(me
, 4);
1179 /* "transferring" operand */
1180 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1182 /* copy ROW registers: must all exist if 4th operand exists */
1183 me
->regs
[PKE_REG_R0
][0] = * pke_pc_operand(me
, 1);
1184 me
->regs
[PKE_REG_R1
][0] = * pke_pc_operand(me
, 2);
1185 me
->regs
[PKE_REG_R2
][0] = * pke_pc_operand(me
, 3);
1186 me
->regs
[PKE_REG_R3
][0] = * pke_pc_operand(me
, 4);
1189 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1190 pke_pc_advance(me
, 5);
1194 /* need to wait for another word */
1195 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1196 /* try again next cycle */
1202 pke_code_stcol(struct pke_device
* me
, unsigned_4 pkecode
)
1204 /* check that FIFO has four more words for STCOL operand */
1205 unsigned_4
* last_op
;
1207 last_op
= pke_pc_operand(me
, 4);
1210 /* "transferring" operand */
1211 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1213 /* copy COL registers: must all exist if 4th operand exists */
1214 me
->regs
[PKE_REG_C0
][0] = * pke_pc_operand(me
, 1);
1215 me
->regs
[PKE_REG_C1
][0] = * pke_pc_operand(me
, 2);
1216 me
->regs
[PKE_REG_C2
][0] = * pke_pc_operand(me
, 3);
1217 me
->regs
[PKE_REG_C3
][0] = * pke_pc_operand(me
, 4);
1220 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1221 pke_pc_advance(me
, 5);
1225 /* need to wait for another word */
1226 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1227 /* try again next cycle */
1233 pke_code_mpg(struct pke_device
* me
, unsigned_4 pkecode
)
1235 unsigned_4
* last_mpg_word
;
1236 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1237 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1239 /* map zero to max+1 */
1240 if(num
==0) num
=0x100;
1242 /* check that FIFO has a few more words for MPG operand */
1243 last_mpg_word
= pke_pc_operand(me
, num
*2); /* num: number of 64-bit words */
1244 if(last_mpg_word
!= NULL
)
1246 /* perform implied FLUSHE */
1247 /* read VU status word */
1250 (SIM_ADDR
) (me
->pke_number
== 0 ? VPE0_STAT
: VPE1_STAT
),
1252 sizeof(unsigned_4
));
1254 /* check if VBS bit is clear, i.e., VU is idle */
1255 if(BIT_MASK_GET(vu_stat
, VU_REG_STAT_VBS_B
, VU_REG_STAT_VBS_E
) == 0)
1260 /* "transferring" operand */
1261 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1263 /* transfer VU instructions, one word per iteration */
1264 for(i
=0; i
<num
*2; i
++)
1266 address_word vu_addr_base
, vu_addr
;
1267 address_word vutrack_addr_base
, vutrack_addr
;
1268 unsigned_4
* operand
;
1269 struct fifo_quadword
* fq
= pke_pc_fifo(me
, num
, & operand
);
1271 /* imm: in 64-bit units for MPG instruction */
1275 /* VU*_MEM0 : instruction memory */
1276 vu_addr_base
= (me
->pke_number
== 0) ?
1277 VU0_MEM0_WINDOW_START
: VU0_MEM0_WINDOW_START
;
1278 vu_addr
= vu_addr_base
+ (imm
*2) + i
;
1280 /* VU*_MEM0_TRACK : source-addr tracking table */
1281 vutrack_addr_base
= (me
->pke_number
== 0) ?
1282 VU0_MEM0_SRCADDR_START
: VU1_MEM0_SRCADDR_START
;
1283 vutrack_addr
= vu_addr_base
+ (imm
*2) + i
;
1285 /* write data into VU memory */
1286 pke_track_write(me
, operand
, sizeof(unsigned_4
),
1287 vu_addr
, fq
->source_address
);
1289 /* write srcaddr into VU srcaddr tracking table */
1291 (SIM_ADDR
) vutrack_addr
,
1292 (void*) & fq
->source_address
,
1293 sizeof(unsigned_4
));
1294 } /* VU xfer loop */
1297 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1298 pke_pc_advance(me
, 1 + num
*2);
1303 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_STALL
);
1304 /* retry this instruction next clock */
1306 } /* if FIFO full enough */
1309 /* need to wait for another word */
1310 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1311 /* retry this instruction next clock */
1317 pke_code_direct(struct pke_device
* me
, unsigned_4 pkecode
)
1319 /* check that FIFO has a few more words for DIRECT operand */
1320 unsigned_4
* last_direct_word
;
1321 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1322 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1324 /* map zero to max+1 */
1325 if(imm
==0) imm
=0x10000;
1327 last_direct_word
= pke_pc_operand(me
, imm
*4); /* num: number of 128-bit words */
1328 if(last_direct_word
!= NULL
)
1334 /* "transferring" operand */
1335 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1337 /* transfer GPUIF quadwords, one word per iteration */
1338 for(i
=0; i
<imm
*4; i
++)
1340 unsigned_4
* operand
;
1341 struct fifo_quadword
* fq
= pke_pc_fifo(me
, num
, &operand
);
1343 /* collect word into quadword */
1344 fifo_data
[i
%4] = *operand
;
1346 /* write to GPUIF FIFO only with full word */
1349 address_word gpuif_fifo
= GPUIF_PATH2_FIFO_ADDR
+(i
/4);
1350 pke_track_write(me
, fifo_data
, sizeof(quadword
),
1351 (SIM_ADDR
) gpuif_fifo
, fq
->source_address
);
1352 } /* write collected quadword */
1354 } /* GPUIF xfer loop */
1357 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1358 pke_pc_advance(me
, 1 + imm
*4);
1359 } /* if FIFO full enough */
1362 /* need to wait for another word */
1363 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1364 /* retry this instruction next clock */
1370 pke_code_directhl(struct pke_device
* me
, unsigned_4 pkecode
)
1372 /* treat the same as DIRECTH */
1373 pke_code_direct(me
, pkecode
);
1378 pke_code_unpack(struct pke_device
* me
, unsigned_4 pkecode
)
1380 int imm
= BIT_MASK_GET(pkecode
, PKE_OPCODE_IMM_B
, PKE_OPCODE_IMM_E
);
1381 int cmd
= BIT_MASK_GET(pkecode
, PKE_OPCODE_CMD_B
, PKE_OPCODE_CMD_E
);
1382 int num
= BIT_MASK_GET(pkecode
, PKE_OPCODE_NUM_B
, PKE_OPCODE_NUM_E
);
1384 short vn
= BIT_MASK_GET(cmd
, 2, 3);
1385 short vl
= BIT_MASK_GET(cmd
, 0, 1);
1386 short vnvl
= BIT_MASK_GET(cmd
, 0, 3);
1387 int m
= BIT_MASK_GET(cmd
, 4, 4);
1388 short cl
= PKE_REG_MASK_GET(me
, CYCLE
, CL
);
1389 short wl
= PKE_REG_MASK_GET(me
, CYCLE
, WL
);
1390 int n
, num_operands
;
1391 unsigned_4
* last_operand_word
;
1393 /* map zero to max+1 */
1394 if(num
==0) num
=0x100;
1396 /* compute PKEcode length, as given in CPU2 spec, v2.1 pg. 11 */
1400 n
= cl
* (num
/wl
) + PKE_LIMIT(num
% wl
, cl
);
1401 num_operands
= (((sizeof(unsigned_4
) >> vl
) * (vn
+1) * n
)/sizeof(unsigned_4
));
1403 /* confirm that FIFO has enough words in it */
1404 last_operand_word
= pke_pc_operand(me
, num_operands
);
1405 if(last_operand_word
!= NULL
)
1407 address_word vu_addr_base
;
1408 int operand_num
, vector_num
;
1410 /* "transferring" operand */
1411 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_XFER
);
1413 /* don't check whether VU is idle */
1415 if(me
->pke_number
== 0)
1416 vu_addr_base
= VU0_MEM1_WINDOW_START
+ BIT_MASK_GET(imm
, 0, 9);
1419 vu_addr_base
= VU1_MEM1_WINDOW_START
+ BIT_MASK_GET(imm
, 0, 9);
1420 if(BIT_MASK_GET(imm
, 15, 15)) /* fetch R flag from imm word */
1421 vu_addr_base
+= PKE_REG_MASK_GET(me
, TOPS
, TOPS
);
1424 /* XXX: vu_addr overflow check */
1426 /* transfer given number of vectors */
1427 operand_num
= 1; /* word index into instruction stream: 1..num_operands */
1428 vector_num
= 0; /* vector number being processed: 0..num-1 */
1429 while(operand_num
<= num_operands
)
1431 quadword vu_old_data
;
1432 quadword vu_new_data
;
1433 quadword unpacked_data
;
1434 address_word vu_addr
;
1435 struct fifo_quadword
* fq
;
1440 /* compute VU destination address, as bytes in R5900 memory */
1443 /* map zero to max+1 */
1444 if(wl
== 0) wl
= 0x0100;
1445 vu_addr
= vu_addr_base
+ 16*(cl
*(vector_num
/wl
) + (vector_num
%wl
));
1448 vu_addr
= vu_addr_base
+ 16*vector_num
;
1450 /* read old VU data word at address */
1451 sim_read(NULL
, (SIM_ADDR
) vu_addr
, (void*) & vu_old_data
, sizeof(vu_old_data
));
1453 /* Let sourceaddr track the first operand */
1454 fq
= pke_pc_fifo(me
, operand_num
, NULL
);
1456 /* For cyclic unpack, next operand quadword may come from instruction stream
1458 if((cl
< wl
) && ((vector_num
% wl
) >= cl
)) /* wl != 0, set above */
1460 /* clear operand - used only in a "indeterminate" state */
1461 for(i
= 0; i
< 4; i
++)
1462 unpacked_data
[i
] = 0;
1466 /* compute unpacked words from instruction stream */
1469 case PKE_UNPACK_S_32
:
1470 case PKE_UNPACK_V2_32
:
1471 case PKE_UNPACK_V3_32
:
1472 case PKE_UNPACK_V4_32
:
1473 /* copy (vn+1) 32-bit values */
1474 for(i
= 0; i
< vn
+1; i
++)
1476 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1477 unpacked_data
[i
] = *operand
;
1482 case PKE_UNPACK_S_16
:
1483 case PKE_UNPACK_V2_16
:
1484 case PKE_UNPACK_V3_16
:
1485 case PKE_UNPACK_V4_16
:
1486 /* copy (vn+1) 16-bit values, packed two-per-word */
1487 for(i
=0; i
<vn
+1; i
+=2)
1489 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1490 unpacked_data
[i
] = BIT_MASK_GET_SX(*operand
, 0, 15, 31);
1491 unpacked_data
[i
+1] = BIT_MASK_GET_SX(*operand
, 16, 31, 31);
1496 case PKE_UNPACK_S_8
:
1497 case PKE_UNPACK_V2_8
:
1498 case PKE_UNPACK_V3_8
:
1499 case PKE_UNPACK_V4_8
:
1500 /* copy (vn+1) 8-bit values, packed four-per-word */
1501 for(i
=0; i
<vn
+1; i
+=4)
1503 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1504 unpacked_data
[i
] = BIT_MASK_GET_SX(*operand
, 0, 7, 31);
1505 unpacked_data
[i
+1] = BIT_MASK_GET_SX(*operand
, 8, 15, 31);
1506 unpacked_data
[i
+2] = BIT_MASK_GET_SX(*operand
, 16, 23, 31);
1507 unpacked_data
[i
+3] = BIT_MASK_GET_SX(*operand
, 24, 31, 31);
1512 case PKE_UNPACK_V4_5
:
1513 /* copy four 1/5/5/5-bit values, packed into a sixteen-bit */
1514 for(i
=0; i
<vn
+1; i
+=4)
1516 unsigned_4
* operand
= pke_pc_operand(me
, operand_num
);
1517 unpacked_data
[i
] = BIT_MASK_GET_SX(*operand
, 0, 4, 31);
1518 unpacked_data
[i
+1] = BIT_MASK_GET_SX(*operand
, 5, 9, 31);
1519 unpacked_data
[i
+2] = BIT_MASK_GET_SX(*operand
, 10, 14, 31);
1520 unpacked_data
[i
+3] = BIT_MASK_GET_SX(*operand
, 15, 15, 31);
1525 /* XXX: handle multiple rows of data in same word */
1526 /* clue: increment operand_num less frequently */
1528 default: /* bad UNPACK code */
1530 /* treat as illegal instruction */
1531 pke_code_error(me
, pkecode
);
1537 /* compute replacement word - function of vn, vl, mask */
1538 if(m
) /* use mask register? */
1540 /* compute index into mask register for this word */
1541 int mask_index
= PKE_LIMIT(vector_num
% wl
, 3); /* wl != 0, set above */
1543 for(i
=0; i
<3; i
++) /* loop over columns */
1545 int mask_op
= PKE_MASKREG_GET(me
, mask_index
, i
);
1546 unsigned_4
* masked_value
= NULL
;
1547 unsigned_4 zero
= 0;
1551 case PKE_MASKREG_INPUT
:
1552 /* for vn == 0, all columns are copied from column 0 */
1554 masked_value
= & unpacked_data
[0];
1556 masked_value
= & zero
; /* arbitrary data: undefined in spec */
1558 masked_value
= & unpacked_data
[i
];
1561 case PKE_MASKREG_ROW
: /* exploit R0..R3 contiguity */
1562 masked_value
= & me
->regs
[PKE_REG_R0
+ i
][0];
1565 case PKE_MASKREG_COLUMN
: /* exploit C0..C3 contiguity */
1566 masked_value
= & me
->regs
[PKE_REG_C0
+ PKE_LIMIT(vector_num
,3)][0];
1569 case PKE_MASKREG_NOTHING
:
1570 /* "write inhibit" by re-copying old data */
1571 masked_value
= & vu_old_data
[i
];
1576 /* no other cases possible */
1579 /* copy masked value for column */
1580 memcpy(& vu_new_data
[i
], masked_value
, sizeof(unsigned_4
));
1581 } /* loop over columns */
1585 /* no mask - just copy over entire unpacked quadword */
1586 memcpy(vu_new_data
, unpacked_data
, sizeof(unpacked_data
));
1589 /* process STMOD register for accumulation operations */
1590 switch(PKE_REG_MASK_GET(me
, MODE
, MDE
))
1592 case PKE_MODE_ADDROW
: /* add row registers to output data */
1594 /* exploit R0..R3 contiguity */
1595 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1598 case PKE_MODE_ACCROW
: /* add row registers to output data; accumulate */
1601 /* exploit R0..R3 contiguity */
1602 vu_new_data
[i
] += me
->regs
[PKE_REG_R0
+ i
][0];
1603 me
->regs
[PKE_REG_R0
+ i
][0] = vu_new_data
[i
];
1607 case PKE_MODE_INPUT
: /* pass data through */
1612 /* write replacement word */
1613 pke_track_write(me
, vu_new_data
, sizeof(vu_new_data
),
1614 (SIM_ADDR
) vu_addr
, fq
->source_address
);
1616 /* next vector please */
1618 } /* vector transfer loop */
1621 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1622 pke_pc_advance(me
, num_operands
);
1623 } /* PKE FIFO full enough */
1626 /* need to wait for another word */
1627 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_WAIT
);
1628 /* retry this instruction next clock */
1634 pke_code_error(struct pke_device
* me
, unsigned_4 pkecode
)
1636 /* set ER1 flag in STAT register */
1637 PKE_REG_MASK_SET(me
, STAT
, ER1
, 1);
1638 /* advance over faulty word */
1639 PKE_REG_MASK_SET(me
, STAT
, PPS
, PKE_REG_STAT_PPS_IDLE
);
1640 pke_pc_advance(me
, 1);