Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "utils.h"
- #include <stdio.h>
- #include <stdlib.h>
- /* Sign extends the given field to a 32-bit integer where field is
- * interpreted an n-bit integer. */
- int sign_extend_number( unsigned int field, unsigned int n) {
- /* YOUR CODE HERE */
- if ((field >> (n - 1)) == 1) {
- return ((field << (32 - n) >> (32 - n)) | (0xFFFFFFFF << n));
- }
- return (field << (32 - n) >> (32 - n));
- }
- /* Unpacks the 32-bit machine code instruction given into the correct
- * type within the instruction struct */
- Instruction parse_instruction(uint32_t instruction_bits) {
- /* YOUR CODE HERE */
- Instruction instruction;
- unsigned int opcode;
- opcode = instruction_bits << (32 - 7) >> (32 - 7);
- switch(opcode) {
- case 0x33:
- instruction.rtype.opcode = opcode;
- instruction.rtype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.rtype.funct3 = instruction_bits >> 12 << 17 >> 17;
- instruction.rtype.rs1 = instruction_bits >> 15 << 12 >> 12;
- instruction.rtype.rs2 = instruction_bits >> 20 << 7 >> 7;
- instruction.rtype.funct7 = instruction_bits >> 25;
- case 0x13:
- instruction.itype.opcode = opcode;
- instruction.itype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.itype.funct3 = instruction_bits >> 12 << 17 >> 17;
- instruction.itype.rs1 = instruction_bits >> 15 << 12 >> 12;
- instruction.itype.imm = instruction_bits >> 20;
- case 0x3:
- instruction.itype.opcode = opcode;
- instruction.itype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.itype.funct3 = instruction_bits >> 12 << 17 >> 17;
- instruction.itype.rs1 = instruction_bits >> 15 << 12 >> 12;
- instruction.itype.imm = instruction_bits >> 20;
- case 0x23:
- instruction.stype.opcode = opcode;
- instruction.stype.imm5 = instruction_bits >> 7 << 20 >> 20;
- instruction.stype.funct3 = instruction_bits >> 12 << 17 >> 17;
- instruction.stype.rs1 = instruction_bits >> 15 << 12 >> 12;
- instruction.stype.rs2 = instruction_bits >> 20 << 7 >> 7;
- instruction.stype.imm7 = instruction_bits >> 25;
- case 0x63:
- instruction.sbtype.opcode = opcode;
- instruction.sbtype.imm5 = instruction_bits >> 7 << 20 >> 20;
- instruction.sbtype.funct3 = instruction_bits >> 12 << 17 >> 17;
- instruction.sbtype.rs1 = instruction_bits >> 15 << 12 >> 12;
- instruction.sbtype.rs2 = instruction_bits >> 20 << 7 >> 7;
- instruction.sbtype.imm7 = instruction_bits >> 25;
- case 0x37:
- instruction.utype.opcode = opcode;
- instruction.utype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.utype.imm = instruction_bits >> 12;
- case 0x6F:
- instruction.ujtype.opcode = opcode;
- instruction.ujtype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.ujtype.imm = instruction_bits >> 12;
- case 0x73:
- instruction.itype.opcode = opcode;
- instruction.itype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.itype.funct3 = instruction_bits >> 12 << 17 >> 17;
- instruction.itype.rs1 = instruction_bits >> 15 << 12 >> 12;
- instruction.itype.imm = instruction_bits >> 20;
- default: // undefined opcode
- instruction.utype.opcode = opcode;
- instruction.utype.rd = instruction_bits >> 7 << 20 >> 20;
- instruction.utype.imm = instruction_bits >> 12;
- }
- return instruction;
- }
- /* Return the number of bytes (from the current PC) to the branch label using the given
- * branch instruction */
- int get_branch_offset(Instruction instruction) {
- /* YOUR CODE HERE */
- unsigned int eleventh = instruction.sbtype.imm5 << 31 >> 31 << 11;
- unsigned int twelfth = instruction.sbtype.imm7 << 25 >> 31 << 12;
- unsigned int firsttofourth = instruction.sbtype.imm5 >> 1 << 1;
- unsigned int fifthtotenth = instruction.sbtype.imm7 << 26 >> 26 << 5;
- unsigned int imm = (twelfth | eleventh | fifthtotenth | firsttofourth);
- return imm;
- }
- /* Returns the number of bytes (from the current PC) to the jump label using the given
- * jump instruction */
- int get_jump_offset(Instruction instruction) {
- /* YOUR CODE HERE */
- unsigned int twentieth = instruction.ujtype.imm << 12 >> 31 << 20;
- unsigned int twelfthtonineteenth = instruction.ujtype.imm << 24 >> 24 << 12;
- unsigned int eleventh = instruction.ujtype.imm << 23 >> 31 << 11;
- unsigned int firsttotenth = instruction.ujtype.imm >> 9 << 21 >> 21 << 1;
- unsigned int imm = (twentieth | twelfthtonineteenth | eleventh | firsttotenth);
- return imm;
- }
- int get_store_offset(Instruction instruction) {
- /* YOUR CODE HERE */
- return sign_extend_number((instruction.stype.imm7 << 5) | instruction.stype.imm5, 12);
- }
- void handle_invalid_instruction(Instruction instruction) {
- printf("Invalid Instruction: 0x%08x\n", instruction.bits);
- }
- void handle_invalid_read(Address address) {
- printf("Bad Read. Address: 0x%08x\n", address);
- exit(-1);
- }
- void handle_invalid_write(Address address) {
- printf("Bad Write. Address: 0x%08x\n", address);
- exit(-1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement