/*----------------------------------------------------------------*\ Ficheiro: ARITHROM.C Alteração: 03-05-96 ALterado por: A.Esteves \*----------------------------------------------------------------*/ #include "datadef.h" /* OPERAÇÕES ARITMÉTICAS */ void arith_this (void) /* MD0,NOT_MD0 | MD1,NOT_MD1,NOT_TAG_IN,TAG_IN | ZERO,CY_IN,UM */ { WORD aux[SIZE]; /* cy = alu_output ( CY_OUT ) */ /* tag = alu_output ( SUM ) */ /* (1 EXOR expressao = not(expressao) */ switch (linhas) { case 111 : /* MD0 MD1 CY_IN */ cy[0] = ((md0[0] ^ md1[0]) & cy[0]) | (md0[0] & md1[0]); cy[1] = ((md0[1] ^ md1[1]) & cy[1]) | (md0[1] & md1[1]); tag[0] = cy[0] ^ (md0[0] ^ md1[0]); tag[1] = cy[1] ^ (md0[1] ^ md1[1]); break; case 113 : /* MD0 MD1 UM */ cy[0] = (md0[0] ^ md1[0]) | (md0[0] & md1[0]); cy[1] = (md0[1] ^ md1[1]) | (md0[1] & md1[1]); tag[0] = ~(md0[0] ^ md1[0]); tag[1] = ~(md0[1] ^ md1[1]); break; case 114 : /* MD0 MD1 ZERO */ cy[0] = (md0[0] & md1[0]); cy[1] = (md0[1] & md1[1]); tag[0] = (md0[0] ^ md1[0]); /* 1 EXOR exp = NOT(exp) */ tag[1] = (md0[1] ^ md1[1]); break; case 131 : /* MD0 NOT_MD1 CY_IN */ cy[0] = ((md0[0] ^ (~md1[0])) & cy[0]) | (md0[0] & (~md1[0])); cy[1] = ((md0[1] ^ (~md1[1])) & cy[1]) | (md0[1] & (~md1[1])); tag[0] = cy[0] ^ (md0[0] ^ (~md1[0])); tag[1] = cy[1] ^ (md0[1] ^ (~md1[1])); break; case 133 : /* MD0 NOT_MD1 UM */ cy[0] = (md0[0] ^ (~md1[0])) | (md0[0] & (~md1[0])); cy[1] = (md0[1] ^ (~md1[1])) | (md0[1] & (~md1[1])); tag[0] = ~(md0[0] ^ (~md1[0])); tag[1] = ~(md0[1] ^ (~md1[1])); break; case 141 : /* MD0 TAG_IN CY_IN */ aux[0] = tag[0]; aux[1] = tag[1]; tag[0] = cy[0] ^ (md0[0] ^ tag[0]); tag[1] = cy[1] ^ (md0[1] ^ tag[1]); cy[0] = ((md0[0] ^ aux[0]) & cy[0]) | (md0[0] & aux[0]); cy[1] = ((md0[1] ^ aux[1]) & cy[1]) | (md0[1] & aux[1]); break; case 143 : /* MD0 TAG_IN UM */ cy[0] = ((md0[0] ^ tag[0]) ) | (md0[0] & tag[0]); cy[1] = ((md0[1] ^ tag[1]) ) | (md0[1] & tag[1]); tag[0] = ~(md0[0] ^ tag[0]); tag[1] = ~(md0[1] ^ tag[1]); break; case 311 : /* NOT_MD0 MD1 CY_IN */ tag[0] = cy[0] ^ ((~md0[0]) ^ md1[0]); tag[1] = cy[1] ^ ((~md0[1]) ^ md1[1]); cy[0] = (((~md0[0]) ^ md1[0]) & cy[0]) | ((~md0[0]) & md1[0]); cy[1] = (((~md0[1]) ^ md1[1]) & cy[1]) | ((~md0[1]) & md1[1]); break; case 313 : /* NOT_MD0 MD1 UM */ cy[0] = ((~md0[0]) ^ md1[0]) | ((~md0[0]) & md1[0]); cy[1] = ((~md0[1]) ^ md1[1]) | ((~md0[1]) & md1[1]); tag[0] = ~((~md0[0]) ^ md1[0]); tag[1] = ~((~md0[1]) ^ md1[1]); break; case 314 : /* NOT_MD0 MD1 ZERO */ cy[0] = ((~md0[0]) & md1[0]); cy[1] = ((~md0[1]) & md1[1]); tag[0] = ((~md0[0]) ^ md1[0]); tag[1] = ((~md0[1]) ^ md1[1]); break; case 331 : /* NOT_MD0 NOT_MD1 CY_IN */ tag[0] = cy[0] ^ ((~md0[0]) ^ (~md1[0])); tag[1] = cy[1] ^ ((~md0[1]) ^ (~md1[1])); cy[0] = (((~md0[0]) ^ (~md1[0])) & cy[0]) | ((~md0[0]) & (~md1[0])); cy[1] = (((~md0[1]) ^ (~md1[1])) & cy[1]) | ((~md0[1]) & (~md1[1])); break; case 333 : /* NOT_MD0 NOT_MD1 UM */ cy[0] = ((~md0[0]) ^ (~md1[0])) | ((~md0[0]) & (~md1[0])); cy[1] = ((~md0[1]) ^ (~md1[1])) | ((~md0[1]) & (~md1[1])); tag[0] = ~((~md0[0]) ^ (~md1[0])); tag[1] = ~((~md0[1]) ^ (~md1[1])); break; case 334 : /* NOT_MD0 NOT_MD1 ZERO */ cy[0] = ((~md0[0]) & (~md1[0])); cy[1] = ((~md0[1]) & (~md1[1])); tag[0] = ((~md0[0]) ^ (~md1[0])); tag[1] = ((~md0[1]) ^ (~md1[1])); break; case 341 : /* NOT_MD0 TAG_IN CY_IN */ aux[0] = tag[0]; aux[1] = tag[1]; tag[0] = cy[0] ^ ((~md0[0]) ^ tag[0]); tag[1] = cy[1] ^ ((~md0[1]) ^ tag[1]); cy[0] = (((~md0[0]) ^ aux[0]) & cy[0]) | ((~md0[0]) & aux[0]); cy[1] = (((~md0[1]) ^ aux[1]) & cy[1]) | ((~md0[1]) & aux[1]); break; /* case 343 : NOT_MD0 TAG_IN UM cy[0] = (((~md0[0]) ^ tag[0]) ) | ((~md0[0]) & tag[0]); cy[1] = (((~md0[1]) ^ tag[1]) ) | ((~md0[1]) & tag[1]); tag[0] = ~((~md0[0]) ^ tag[0]); tag[1] = ~((~md0[1]) ^ tag[1]); break; */ case 344 : /* NOT_MD0 TAG_IN ZERO */ cy[0] = ((~md0[0]) & tag[0]); cy[1] = ((~md0[1]) & tag[1]); tag[0] = ((~md0[0]) ^ tag[0]); tag[1] = ((~md0[1]) ^ tag[1]); break; case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ aux[0] = tag[0]; aux[1] = tag[1]; tag[0] = cy[0] ^ ((~md0[0]) ^ (~tag[0])); tag[1] = cy[1] ^ ((~md0[1]) ^ (~tag[1])); cy[0] = (((~md0[0]) ^ (~aux[0])) & cy[0]) | ((~md0[0]) & (~aux[0])); cy[1] = (((~md0[1]) ^ (~aux[1])) & cy[1]) | ((~md0[1]) & (~aux[1])); break; case 353 : /* NOT_MD0 NOT_TAG_IN UM */ cy[0] = ((~md0[0]) ^ (~tag[0])) | ((~md0[0]) & (~tag[0])); cy[1] = ((~md0[1]) ^ (~tag[1])) | ((~md0[1]) & (~tag[1])); tag[0] = ~((~md0[0]) ^ (~tag[0])); tag[1] = ~((~md0[1]) ^ (~tag[1])); break; default : erro("\nERRO na funcao arith_this(). \n"); break; } } /*--------------------------------------------------------------*/ void arith_above (void) /* MD0,NOT_MD0 | TAG_IN,NOT_TAG_IN | ZERO,CY_IN,UM */ { /* cy = alu_output ( CY_OUT ) */ /* tag = alu_output ( SUM ) */ /* tag_rout -> above Isto implica que o valor da tag do PE vizinho ser  fornecido como o valor do MD1. Igual   função arith_this excepto que é feito uma "migração" das tags dos PEs "de cima" para os seus vizinhos.*/ /* Preparar as tags */ TagAbove(); switch (linhas) /* Não se invoca logo arith_this por questões de validação */ { case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN ZERO */ arith_this(); break; default : erro("\nERRO na funcao arith_above(). \n"); break; } } /*--------------------------------------------------------------*/ void arith_below (void) /* MD0,NOT_MD0 | TAG_IN,NOT_TAG_IN | ZERO,CY_IN,UM */ { /* cy = alu_output ( cy_out ) */ /* tag = alu_output ( sum ) */ /* tag_rout -> below Isto implica que o valor da tag do PE vizinho ser  fornecido como o valor do MD1. Igual à função arith_this excepto que é feita uma "migração" das tags dos PEs "de baixo" para os seus vizinhos. */ TagBelow(); /* Preparar as tags */ switch (linhas) /* Nao se invoca logo arith_this por questoes de validacao */ { case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN ZERO */ arith_this(); break; default : erro("\nERRO na funcao arith_below(). \n"); break; } } /*--------------------------------------------------------------*/ void arith_image (void) /* MD0,NOT_MD0 | TAG_IN,NOT_TAG_IN | ZERO,CY_IN,UM */ { /* cy = alu_output ( cy_out ) */ /* tag = alu_output ( sum ) */ /* tag_rout -> image Igual 'a funcao arith_this excepto que e' feito uma atribuicao dos valores vindos do VSR 'a tag. */ TagImage(); /* Preparar as tags */ switch (linhas) /* Nao se invoca logo arith_this por questoes de validacao */ { case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN ZERO */ arith_this(); break; default : erro("\nERRO na funcao arith_image(). \n"); break; } } /*--------------------------------------------------------------*/ void swap_this (void) /* MD0,NOT_MD0 | MD1,NOT_MD1,NOT_TAG_IN,TAG_IN | ZERO,CY_IN,UM */ { WORD aux; /* cy = alu_output (sum) */ /* tag = alu_output (cy_out) */ /* Esta funcao executa o mesmo que arith_this, excepto que, os registos cy e tag estao trocados. Assim, podemos invocar arith_this e em seguida trocar os conteudos dos registos cy e tag. */ switch (linhas) /* Nao se invoca logo arith_this por questoes de validacao */ { case 111 : /* MD0 MD1 CY_IN */ case 113 : /* MD0 MD1 UM */ case 114 : /* MD0 MD1 ZERO */ case 131 : /* MD0 NOT_MD1 CY_IN */ case 133 : /* MD0 NOT_MD1 UM */ case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 311 : /* NOT_MD0 MD1 CY_IN */ case 313 : /* NOT_MD0 MD1 UM */ case 314 : /* NOT_MD0 MD1 ZERO */ case 331 : /* NOT_MD0 NOT_MD1 CY_IN */ case 333 : /* NOT_MD0 NOT_MD1 UM */ case 334 : /* NOT_MD0 NOT_MD1 ZERO */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN UM */ arith_this(); /* FAZER A TROCA */ aux=cy[0]; cy[0]=tag[0]; tag[0]=aux; aux=cy[1]; cy[1]=tag[1]; tag[1]=aux; break; default : erro("\nERRO na funcao swap_this(). \n"); break; } } /*--------------------------------------------------------------*/ void swap_above (void) { WORD aux; /* cy = alu_output (sum) */ /* tag = alu_output (cy_out) */ /* tag_rout -> above Isto implica que o valor da tag do PE vizinho sera' fornecido como o valor do MD1. Igual 'a funcao arith_this excepto que e' feito uma "migracao" das tags dos PEs "de cima" para os seus vizinhos. Alem dessa diferenca, os registos cy e tag estao trocados. Assim, podemos invocar arith_this e em seguida trocar os conteudos dos registos cy e tag. */ TagAbove(); /* Preparar as tags */ switch (linhas) /* Nao se invoca logo arith_this por questoes de validacao */ { case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN ZERO */ arith_this(); /* FAZER A TROCA */ aux=cy[0]; cy[0]=tag[0]; tag[0]=aux; aux=cy[1]; cy[1]=tag[1]; tag[1]=aux; break; default : erro("\nERRO na funcao swap_above(). \n"); break; } } /*--------------------------------------------------------------*/ void swap_below (void) { WORD aux; /* cy = alu_output (sum) */ /* tag = alu_output (cy_out) */ /* tag_rout -> below Isto implica que o valor da tag do PE vizinho ser  fornecido como o valor do MD1. Igual   funcao arith_this excepto que e' feita uma "migracao" das tags dos PEs "de baixo" para os seus vizinhos. Alem dessa diferenca, os registos cy e tag estao trocados. Assim, podemos invocar arith_this e em seguida trocar os conteudos dos registos cy e tag. */ TagBelow(); /* Preparar as tags */ switch (linhas) /* Nao se invoca logo arith_this por questoes de validacao */ { case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN ZERO */ arith_this(); /* FAZER A TROCA */ aux=cy[0]; cy[0]=tag[0]; tag[0]=aux; aux=cy[1]; cy[1]=tag[1]; tag[1]=aux; break; default : erro("\nERRO na funcao swap_below(). \n"); break; } } /*--------------------------------------------------------------*/ void swap_image (void) { WORD aux; /* cy = alu_output (sum) */ /* tag = alu_output (cy_out) */ /* tag_rout -> image Igual 'a funcao arith_this excepto que e' feito uma atribuicao de valores vindos do VSR para as tags. Alem dessa diferenca, os registos cy e tag estao trocados. Assim, podemos invocar arith_this e em seguida trocar os conteudos dos registos cy e tag. */ TagImage(); /* Preparar as tags */ switch (linhas) /* Nao se invoca logo arith_this por questoes de validacao */ { case 141 : /* MD0 TAG_IN CY_IN */ case 143 : /* MD0 TAG_IN UM */ case 341 : /* NOT_MD0 TAG_IN CY_IN */ case 344 : /* NOT_MD0 TAG_IN ZERO */ case 351 : /* NOT_MD0 NOT_TAG_IN CY_IN */ case 353 : /* NOT_MD0 NOT_TAG_IN ZERO */ arith_this(); /* FAZER A TROCA */ aux=cy[0]; cy[0]=tag[0]; tag[0]=aux; aux=cy[1]; cy[1]=tag[1]; tag[1]=aux; break; default : erro("\nERRO na funcao swap_image(). \n"); break; } } /*--------------------------------------------------------------*/ void arithholdms (void) { /* cy = alu_output ( cy_out ) */ /* tag = alu_output ( sum ) */ ms[0]=msbak[0]; /* Hold ms */ ms[1]=msbak[1]; arith_this(); /* A funcao arithholdms invoca arith_this depois de restaurar ms */ } /*--------------------------------------------------------------*/ void swap_holdms (void) { /* cy = alu_output (sum) */ /* tag = alu_output (cy_out) */ ms[0]=msbak[0]; /* Hold ms */ ms[1]=msbak[1]; swap_this(); /* A funcao swap_holdms invoca swap_this depois de restaurar ms */ } /*--------------------------------------------------------------*/