/* Copyright (c) 2014, Ian Sutton * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * This code implements a simple matrix operation in C, to be * cross-compiled into Loongson MIPS 32-bit instructions. */ #ifdef DEBUG #include #endif #include "proto.h" int main(int argc, char *argv[]) { #ifdef HARDCODED_OPERANDS /* volatile, otherwise GCC optimizations muddy things up. 'a' and * 'b' are our starting matricies */ volatile int a[MS][MS] = { { 1, 2, 3}, { 4, 5, 6}, { 7, 8, 9} }; volatile int b[MS][MS] = { { 1, 4, 7}, { 2, 5, 8}, { 3, 6, 9} }; #endif /* 'd' and 'c' are matricies that store the result of the * combinations of 'a' and 'b' prior to multiplication */ volatile int c[MS][MS], d[MS][MS]; /* where our resultant matrix is stored */ volatile int result[MS][MS]; /* zero-out our result buffers */ matrix_init0(c); matrix_init0(d); matrix_init0(result); /* first we combine A + B and store it in C */ matrix_add(a, b, c); /* then we subtract A - B and store it in D */ matrix_sub(a, b, d); /* finally, we multiply A * B and store it in result */ matrix_mult(a, b, result); #ifdef DEBUG printf("Matrix A:\n"); matrix_print(a); printf("\nMatrix B:\n"); matrix_print(b); printf("\nAdded Matrix (A + B) -> C:\n"); matrix_print(c); printf("\nSubtracted Matrix (A - B) -> D:\n"); matrix_print(d); printf("\nMultiplied Matrix (C * D) -> Result:\n"); matrix_print(result); #endif return 0; } static void matrix_add(volatile int op1[MS][MS], volatile int op2[MS][MS], volatile int result_buf[MS][MS]) { int i, j; i = 0; j = 0; for(; i < MS; i++) { j = 0; for(; j < MS; j++) result_buf[i][j] = op1[i][j] + op2[i][j]; } } static void matrix_sub(volatile int op1[MS][MS], volatile int op2[MS][MS], volatile int result_buf[MS][MS]) { int i, j; i = 0; j = 0; for(; i < MS; i++) { j = 0; for(; j < MS; j++) result_buf[i][j] = op1[i][j] - op2[i][j]; } } static void matrix_mult(volatile int op1[MS][MS], volatile int op2[MS][MS], volatile int result_buf[MS][MS]) { int i, j, k; i = 0; j = 0; k = 0; for(; i < MS; i++) { j = 0; for(; j < MS; j++) { k = 0; for(; k < MS; k++) result_buf[i][j] += op1[i][k] * op2[k][j]; } } } static void matrix_init0(volatile int matrix[MS][MS]) { int i, j; i = 0; j = 0; for(; i < MS; i++) { j = 0; for(; j < MS; j++) matrix[i][j] = 0; } } #ifdef DEBUG static void matrix_print(volatile int matrix[MS][MS]) { int i,j; i = 0; j = 0; printf("\t┌────────────┐\n"); for(; i < MS; i++) { printf("\t│"); j = 0; for(; j < MS; j++) { printf("%3d", matrix[i][j]); if(j + 1 != MS) printf(" "); } printf(" │\n"); } printf("\t└────────────┘\n"); } #endif