CSAPP 第三版 第四章 家庭作业and so on

CSAPP 第三版 第四章 作业
自己做的 仅供参考 可能出现错误

注:内容有点多还挺难,挖个坑后续有时间再填。。。

参考:https://blog.csdn.net/one_of_a_kind/article/details/81836111

4.45

A.不能,压入的是%rsp-8

B.

movq REG, -0x8(%rsp)
subq $8, %rsp

4.46

A.不能,弹出的是%rsp+8

B.

addq $8, %rsp
movq -0x8(%rsp), REG

4.47

使用数组索引

/* Bubble sort: Array version */
void bubble_a(long *data, long count) {
	long i, last;
	for (last = count - 1; last > 0; last--) {
		for (i = 0; i < last; i++) {
			if (data[i + 1] < data[i]) {
				/*Swap adjacent elements*/
				long t = data[i + 1];
				data[i + 1] = data[i];
				data[i] = t;
			}
		}
	}
}

A.

/* Bubble sort: Pointer version */
void bubble_b(long *data, long count) {
	long i, last;
	for (last = count - 1; last > 0; last--) {
		for (i = 0; i < last; i++) {
			if (*(data + i + 1)< *(data + i)) {
				/*Swap adjacent elements*/
				long t = *(data + i + 1);
				*(data + i + 1) = *(data + i);
				*(data + i) = t;
			}
		}
	}
}

B.
先使用以下C程序在Ubuntu 16.04 LTS下gcc生成汇编代码:

#include <stdio.h>
long arr[] = {0xabc, 0xbc, 0xc, 0x1};
void bubble_b(long *data, long count) {
	long i, last;
	for (last = count - 1; last > 0; last--) {
		for (i = 0; i < last; i++) {
			if (*(data + i + 1)< *(data + i)) {
				/*Swap adjacent elements*/
				long t = *(data + i + 1);
				*(data + i + 1) = *(data + i);
				*(data + i) = t;
			}
		}
	}
}
int main(){
	bubble_b(arr, 4);
	return 0;
}

生成的x86-64汇编代码如下(-O1下):

	.file	"bubble.c"
	.text
	.globl	bubble_b
	.type	bubble_b, @function
bubble_b:
.LFB23:
	.cfi_startproc
	leaq	-1(%rsi), %r8
	testq	%r8, %r8
	jle	.L1
	leaq	(%rdi,%rsi,8), %rsi
	jmp	.L3
.L5:
	movq	(%rax), %rdx
	movq	-8(%rax), %rcx
	cmpq	%rcx, %rdx
	jge	.L4
	movq	%rcx, (%rax)
	movq	%rdx, -8(%rax)
.L4:
	addq	$8, %rax
	cmpq	%rsi, %rax
	jne	.L5
.L6:
	subq	$8, %rsi
	subq	$1, %r8
	je	.L1
.L3:
	testq	%r8, %r8
	jle	.L6
	leaq	8(%rdi), %rax
	jmp	.L5
.L1:
	rep ret
	.cfi_endproc
.LFE23:
	.size	bubble_b, .-bubble_b
	.globl	main
	.type	main, @function
main:
.LFB24:
	.cfi_startproc
	movl	$4, %esi
	movl	$arr, %edi
	call	bubble_b
	movl	$0, %eax
	ret
	.cfi_endproc
.LFE24:
	.size	main, .-main
	.globl	arr
	.data
	.align 32
	.type	arr, @object
	.size	arr, 32
arr:
	.quad	2748
	.quad	188
	.quad	12
	.quad	1
	.ident	"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609"
	.section	.note.GNU-stack,"",@progbits

于是根据该汇编代码以及图4-7可以写出Y86-64程序:

	# Execution begins at address
	.pos 0
	irmovq stack, %rsp      # Set up stack pointer
	call main               # Execute main program
	halt                    # Terminate program

	# Array of 4 elements
	.align 8
arr:
	.quad	2748
	.quad	188
	.quad	12
	.quad	1

main:	
    irmovq array,%rdi
	irmovq $4,%rsi
	call bubble_b		    # bubble(array, 4)
	ret

# void bubble_b(long *data, long count)
# data in %rdi, count in %rsi
bubble_b:
	irmovq $1, %r8			# Constant 1
	irmovq $8, %r9			# Constant 8
	rrmovq %rsi, %rax		
	subq %r8, %rax			# last--
	je done					# Stop when last == 0
loop1:
	xorq %rcx, %rcx			# i = 0
loop2:
	rrmovq %rcx, %rdx		# %rdx = i
	addq %rdx, %rdx			# %rdx = 2 * i
	addq %rdx, %rdx			# %rdx = 4 * i
	addq %rdx, %rdx			# %rdx = 8 * i
	addq %rdi, %rdx			# %rdx = data + 8 * i
	mrmovq (%rdx), %r10		# %r10 = data[i]
	addq %r9, %rdx			# %rdx = data + 8 * i + 8
	mrmovq (%rdx), %rbx		# %rbx = data[i + 1]
	rrmovq %rbx, %r11		# %r11 = data[i + 1]
	subq %r10, %rbx			# %rbx = data[i + 1] - data[i]
	jge test				# data[i + 1] - data[i] > 0 Goto test
	rmmovq %r10, (%rdx)		# data[i + 1] = data[i]
	subq %r9, %rdx			# %rdx = %rdx - 8
	rmmovq %r11, (%rdx)		# data[i] = data[i + 1]
test:
	addq %r8, %rcx			# i++
	rrmovq %rcx, %r12		# %r12 = %rcx = i
	subq %rax, %r12			# i - last		
	jl loop2				# i < last
	subq %r8, %rax			# last--						
	jg loop1				# Stop when last <= 0
done:
	ret                     # Return

# Stack starts here and grows to lower addresses
	.pos 0x200
stack:

测试结果如下:

Memory State:
0x0018:	0x0000000000000001
0x0020:	0x000000000000000c
0x0028:	0x00000000000000bc
0x0030:	0x0000000000000abc

4.48

	# Execution begins at address
	.pos 0
	irmovq stack, %rsp      # Set up stack pointer
	call main               # Execute main program
	halt                    # Terminate program

	# Array of 4 elements
	.align 8
arr:
	.quad	2748
	.quad	188
	.quad	12
	.quad	1

main:	
    irmovq array,%rdi
	irmovq $4,%rsi
	call bubble_b		    # bubble(array, 4)
	ret

# void bubble_b(long *data, long count)
# data in %rdi, count in %rsi
bubble_b:
	irmovq $1, %r8			# Constant 1
	irmovq $8, %r9			# Constant 8
	rrmovq %rsi, %rax		
	subq %r8, %rax			# last--
	je done					# Stop when last == 0
loop1:
	xorq %rcx, %rcx			# i = 0
loop2:
	rrmovq %rcx, %rdx		# %rdx = i
	addq %rdx, %rdx			# %rdx = 2 * i
	addq %rdx, %rdx			# %rdx = 4 * i
	addq %rdx, %rdx			# %rdx = 8 * i
	addq %rdi, %rdx			# %rdx = data + 8 * i
	mrmovq (%rdx), %r10		# %r10 = data[i]
	addq %r9, %rdx			# %rdx = data + 8 * i + 8
	mrmovq (%rdx), %rbx		# %rbx = data[i + 1]
	rrmovq %rbx, %r11		# %r11 = data[i + 1]
	subq %r10, %rbx			# %rbx = data[i + 1] - data[i]
	rrmovq %r11, %r12       # %r12 = data[i + 1]
	rrmovq %r10, %r13       # %r13 = data[i]
	cmovl %r10, %r12		# %r12 = data[i]
	cmovl %r11, %r13		# %r13 = data[i + 1]
	rmmovq %r12, (%rdx)     # data[i + 1] = %r12
	subq %r9, %rdx			# %rdx = %rdx - 8
	rmmovq %r13, (%rdx)     # data[i] = %r13
test:
	addq %r8, %rcx			# i++
	rrmovq %rcx, %r12		# %r12 = %rcx = i
	subq %rax, %r12			# i - last		
	jl loop2				# i < last
	subq %r8, %rax			# last--						
	jg loop1				# Stop when last <= 0
done:
	ret                     # Return

# Stack starts here and grows to lower addresses
	.pos 0x200
stack:

4.49

	# Execution begins at address
	.pos 0
	irmovq stack, %rsp      # Set up stack pointer
	call main               # Execute main program
	halt                    # Terminate program

	# Array of 4 elements
	.align 8
arr:
	.quad	2748
	.quad	188
	.quad	12
	.quad	1

main:	
    irmovq array,%rdi
	irmovq $4,%rsi
	call bubble_b		    # bubble(array, 4)
	ret

# void bubble_b(long *data, long count)
# data in %rdi, count in %rsi
bubble_b:
	irmovq $1, %r8			# Constant 1
	irmovq $8, %r9			# Constant 8
	rrmovq %rsi, %rax		
	subq %r8, %rax			# last--
	je done					# Stop when last == 0
loop1:
	xorq %rcx, %rcx			# i = 0
loop2:
	rrmovq %rcx, %rdx		# %rdx = i
	addq %rdx, %rdx			# %rdx = 2 * i
	addq %rdx, %rdx			# %rdx = 4 * i
	addq %rdx, %rdx			# %rdx = 8 * i
	addq %rdi, %rdx			# %rdx = data + 8 * i
	mrmovq (%rdx), %r10		# %r10 = data[i]
	addq %r9, %rdx			# %rdx = data + 8 * i + 8
	mrmovq (%rdx), %rbx		# %rbx = data[i + 1]
	rrmovq %rbx, %r11		# %r11 = data[i + 1]
	subq %r10, %rbx			# %rbx = data[i + 1] - data[i]
	cmovge %r12, %rbx		# %rbx = data[i + 1] - data[i]
	subq %rbx, %r11         # %r11 = data[i+1] < data[i] : data[i] : data[i+1]
	rmmovq %r11, (%rdx)     # data[i+1] = %r11
	subq %r9, %rdx			# %rdx = %rdx - 8
	addq %rbx, %r10         # %r10 = data[i+1] < data[i] : data[i] : data[i+1]
	rmmovq %r10, (%rdx)     # data[i] = %r10
test:
	addq %r8, %rcx			# i++
	rrmovq %rcx, %r12		# %r12 = %rcx = i
	subq %rax, %r12			# i - last		
	jl loop2				# i < last
	subq %r8, %rax			# last--						
	jg loop1				# Stop when last <= 0
done:
	ret                     # Return

# Stack starts here and grows to lower addresses
	.pos 0x200
stack:

4.50

    # Execution begins at address
	.pos 0
	irmovq stack, %rsp  	# Set up stack pointer
	call main		        # Execute main program
	halt			        # Terminate program 

    # table
	.align 8
table:	
	.quad 0x00000000015e
	.quad 0x00000000017f
	.quad 0x000000000169
	.quad 0x000000000174
	.quad 0x00000000017f
	.quad 0x000000000169
	.quad 0x00000000017f
	
main:
	irmovq $3,%rdi
	call switchv		    # switchv(3)
	ret
	
	.pos 0x100
# long switchv(long idx)
# idx in %rdi
# 0x100
switchv:
	irmovq 0xaaa, %r8		# %r8 = 0xaaa
	irmovq 0xbbb, %r9 		# %r9 = 0xbbb
	irmovq 0xccc, %r10		# %r10 = 0xccc
	irmovq 0xddd, %r11		# %r11 = 0x‭ddd
	irmovq $5, %r12			# %r12 = 5
	irmovq table, %r13		# %r13 = table
	rrmovq %rdi, %rdx       # %rdx = idx
	subq %r12, %rdx			# idx - 5
	jg default				# idx > 5
	addq %rdi, %rdi			# idx = 2 * idx
	addq %rdi, %rdi			# idx = 4 * idx
	addq %rdi, %rdi			# idx = 8 * idx
	addq %rdi, %r13			# %r13 = table + 8 * idx
	mrmovq (%r13), %r13
	pushq %r13
	ret
# 0x15e
	rrmovq %r8, %rax
	jmp done
# 0x169
	rrmovq %r9, %rax
	jmp done
# 0x174
	rrmovq %r10, %rax
	jmp done
# 0x17f
default:
	rrmovq %r11, %rax
done:
	ret
	
# Stack starts here and grows to lower addresses
	.pos 0x200
stack:

4.51

阶段iaddq V, rB
取址icode:ifun <- M1 [PC]
rA:rB <- M1[PC+1]
valC <- M8[PC+2]
valP <- PC+10
译码valB <- R[rB]
执行valE <- valC + valB
访存
写回R[rB] <- valE
更新PCPC <- valP

4.52

这里给出seq-full.hcl文件的内容

#/* $begin seq-all-hcl */
####################################################################
#  HCL Description of Control for Single Cycle Y86-64 Processor SEQ   #
#  Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010       #
####################################################################

## Your task is to implement the iaddq instruction
## The file contains a declaration of the icodes
## for iaddq (IIADDQ)
## Your job is to add the rest of the logic to make it work

####################################################################
#    C Include's.  Don't alter these                               #
####################################################################

quote '#include <stdio.h>'
quote '#include "isa.h"'
quote '#include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'word_t gen_pc(){return 0;}'
quote 'int main(int argc, char *argv[])'
quote '  {plusmode=0;return sim_main(argc,argv);}'

####################################################################
#    Declarations.  Do not change/remove/delete any of these       #
####################################################################

##### Symbolic representation of Y86-64 Instruction Codes #############
wordsig INOP 	'I_NOP'
wordsig IHALT	'I_HALT'
wordsig IRRMOVQ	'I_RRMOVQ'
wordsig IIRMOVQ	'I_IRMOVQ'
wordsig IRMMOVQ	'I_RMMOVQ'
wordsig IMRMOVQ	'I_MRMOVQ'
wordsig IOPQ	'I_ALU'
wordsig IJXX	'I_JMP'
wordsig ICALL	'I_CALL'
wordsig IRET	'I_RET'
wordsig IPUSHQ	'I_PUSHQ'
wordsig IPOPQ	'I_POPQ'
# Instruction code for iaddq instruction
wordsig IIADDQ	'I_IADDQ'

##### Symbolic represenations of Y86-64 function codes                  #####
wordsig FNONE    'F_NONE'        # Default function code

##### Symbolic representation of Y86-64 Registers referenced explicitly #####
wordsig RRSP     'REG_RSP'    	# Stack Pointer
wordsig RNONE    'REG_NONE'   	# Special value indicating "no register"

##### ALU Functions referenced explicitly                            #####
wordsig ALUADD	'A_ADD'		# ALU should add its arguments

##### Possible instruction status values                             #####
wordsig SAOK	'STAT_AOK'	# Normal execution
wordsig SADR	'STAT_ADR'	# Invalid memory address
wordsig SINS	'STAT_INS'	# Invalid instruction
wordsig SHLT	'STAT_HLT'	# Halt instruction encountered

##### Signals that can be referenced by control logic ####################

##### Fetch stage inputs		#####
wordsig pc 'pc'				# Program counter
##### Fetch stage computations		#####
wordsig imem_icode 'imem_icode'		# icode field from instruction memory
wordsig imem_ifun  'imem_ifun' 		# ifun field from instruction memory
wordsig icode	  'icode'		# Instruction control code
wordsig ifun	  'ifun'		# Instruction function
wordsig rA	  'ra'			# rA field from instruction
wordsig rB	  'rb'			# rB field from instruction
wordsig valC	  'valc'		# Constant from instruction
wordsig valP	  'valp'		# Address of following instruction
boolsig imem_error 'imem_error'		# Error signal from instruction memory
boolsig instr_valid 'instr_valid'	# Is fetched instruction valid?

##### Decode stage computations		#####
wordsig valA	'vala'			# Value from register A port
wordsig valB	'valb'			# Value from register B port

##### Execute stage computations	#####
wordsig valE	'vale'			# Value computed by ALU
boolsig Cnd	'cond'			# Branch test

##### Memory stage computations		#####
wordsig valM	'valm'			# Value read from memory
boolsig dmem_error 'dmem_error'		# Error signal from data memory


####################################################################
#    Control Signal Definitions.                                   #
####################################################################

################ Fetch Stage     ###################################

# Determine instruction code
word icode = [
	imem_error: INOP;
	1: imem_icode;		# Default: get from instruction memory
];

# Determine instruction function
word ifun = [
	imem_error: FNONE;
	1: imem_ifun;		# Default: get from instruction memory
];

bool instr_valid = icode in 
	{ INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,
	       IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ,IIADDQ };

# Does fetched instruction require a regid byte?
bool need_regids =
	icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, 
		     IIRMOVQ, IRMMOVQ, IMRMOVQ,IIADDQ };

# Does fetched instruction require a constant word?
bool need_valC =
	icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL,IIADDQ };

################ Decode Stage    ###################################

## What register should be used as the A source?
word srcA = [
	icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ  } : rA;
	icode in { IPOPQ, IRET } : RRSP;
	1 : RNONE; # Don't need register
];

## What register should be used as the B source?
word srcB = [
	icode in { IOPQ, IRMMOVQ, IMRMOVQ,IIADDQ  } : rB;
	icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;
	1 : RNONE;  # Don't need register
];

## What register should be used as the E destination?
word dstE = [
	icode in { IRRMOVQ } && Cnd : rB;
	icode in { IIRMOVQ, IOPQ,IIADDQ} : rB;
	icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;
	1 : RNONE;  # Don't write any register
];

## What register should be used as the M destination?
word dstM = [
	icode in { IMRMOVQ, IPOPQ } : rA;
	1 : RNONE;  # Don't write any register
];

################ Execute Stage   ###################################

## Select input A to ALU
word aluA = [
	icode in { IRRMOVQ, IOPQ } : valA;
	icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ,IIADDQ } : valC;
	icode in { ICALL, IPUSHQ } : -8;
	icode in { IRET, IPOPQ } : 8;
	# Other instructions don't need ALU
];

## Select input B to ALU
word aluB = [
	icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, 
		      IPUSHQ, IRET, IPOPQ,IIADDQ } : valB;
	icode in { IRRMOVQ, IIRMOVQ } : 0;
	# Other instructions don't need ALU
];

## Set the ALU function
word alufun = [
	icode == IOPQ : ifun;
	1 : ALUADD;
];

## Should the condition codes be updated?
bool set_cc = icode in { IOPQ,IIADDQ };

################ Memory Stage    ###################################

## Set read control signal
bool mem_read = icode in { IMRMOVQ, IPOPQ, IRET };

## Set write control signal
bool mem_write = icode in { IRMMOVQ, IPUSHQ, ICALL };

## Select memory address
word mem_addr = [
	icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ } : valE;
	icode in { IPOPQ, IRET } : valA;
	# Other instructions don't need address
];

## Select memory input data
word mem_data = [
	# Value from register
	icode in { IRMMOVQ, IPUSHQ } : valA;
	# Return PC
	icode == ICALL : valP;
	# Default: Don't write anything
];

## Determine instruction status
word Stat = [
	imem_error || dmem_error : SADR;
	!instr_valid: SINS;
	icode == IHALT : SHLT;
	1 : SAOK;
];

################ Program Counter Update ############################

## What address should instruction be fetched at

word new_pc = [
	# Call.  Use instruction constant
	icode == ICALL : valC;
	# Taken branch.  Use instruction constant
	icode == IJXX && Cnd : valC;
	# Completion of RET instruction.  Use value from stack
	icode == IRET : valM;
	# Default: Use incremented PC
	1 : valP;
];
#/* $end seq-all-hcl */

修改实现iaddq指令的控制逻辑块的HCL描述:

#/* $begin new-seq-all-hcl */
####################################################################
#  HCL Description of Control for Single Cycle Y86-64 Processor SEQ   #
#  Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010       #
####################################################################

## Your task is to implement the iaddq instruction
## The file contains a declaration of the icodes
## for iaddq (IIADDQ)
## Your job is to add the rest of the logic to make it work

####################################################################
#    C Include's.  Don't alter these                               #
####################################################################

quote '#include <stdio.h>'
quote '#include "isa.h"'
quote '#include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'word_t gen_pc(){return 0;}'
quote 'int main(int argc, char *argv[])'
quote '  {plusmode=0;return sim_main(argc,argv);}'

####################################################################
#    Declarations.  Do not change/remove/delete any of these       #
####################################################################

##### Symbolic representation of Y86-64 Instruction Codes #############
wordsig INOP 	'I_NOP'
wordsig IHALT	'I_HALT'
wordsig IRRMOVQ	'I_RRMOVQ'
wordsig IIRMOVQ	'I_IRMOVQ'
wordsig IRMMOVQ	'I_RMMOVQ'
wordsig IMRMOVQ	'I_MRMOVQ'
wordsig IOPQ	'I_ALU'
wordsig IJXX	'I_JMP'
wordsig ICALL	'I_CALL'
wordsig IRET	'I_RET'
wordsig IPUSHQ	'I_PUSHQ'
wordsig IPOPQ	'I_POPQ'
# Instruction code for iaddq instruction
wordsig IIADDQ	'I_IADDQ'

##### Symbolic represenations of Y86-64 function codes                  #####
wordsig FNONE    'F_NONE'        # Default function code

##### Symbolic representation of Y86-64 Registers referenced explicitly #####
wordsig RRSP     'REG_RSP'    	# Stack Pointer
wordsig RNONE    'REG_NONE'   	# Special value indicating "no register"

##### ALU Functions referenced explicitly                            #####
wordsig ALUADD	'A_ADD'		# ALU should add its arguments

##### Possible instruction status values                             #####
wordsig SAOK	'STAT_AOK'	# Normal execution
wordsig SADR	'STAT_ADR'	# Invalid memory address
wordsig SINS	'STAT_INS'	# Invalid instruction
wordsig SHLT	'STAT_HLT'	# Halt instruction encountered

##### Signals that can be referenced by control logic ####################

##### Fetch stage inputs		#####
wordsig pc 'pc'				# Program counter
##### Fetch stage computations		#####
wordsig imem_icode 'imem_icode'		# icode field from instruction memory
wordsig imem_ifun  'imem_ifun' 		# ifun field from instruction memory
wordsig icode	  'icode'		# Instruction control code
wordsig ifun	  'ifun'		# Instruction function
wordsig rA	  'ra'			# rA field from instruction
wordsig rB	  'rb'			# rB field from instruction
wordsig valC	  'valc'		# Constant from instruction
wordsig valP	  'valp'		# Address of following instruction
boolsig imem_error 'imem_error'		# Error signal from instruction memory
boolsig instr_valid 'instr_valid'	# Is fetched instruction valid?

##### Decode stage computations		#####
wordsig valA	'vala'			# Value from register A port
wordsig valB	'valb'			# Value from register B port

##### Execute stage computations	#####
wordsig valE	'vale'			# Value computed by ALU
boolsig Cnd	'cond'			# Branch test

##### Memory stage computations		#####
wordsig valM	'valm'			# Value read from memory
boolsig dmem_error 'dmem_error'		# Error signal from data memory


####################################################################
#    Control Signal Definitions.                                   #
####################################################################

################ Fetch Stage     ###################################

# Determine instruction code
word icode = [
	imem_error: INOP;
	1: imem_icode;		# Default: get from instruction memory
];

# Determine instruction function
word ifun = [
	imem_error: FNONE;
	1: imem_ifun;		# Default: get from instruction memory
];

bool instr_valid = icode in 
	{ INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,
	       IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ };

# Does fetched instruction require a regid byte?
bool need_regids =
	icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, 
		     IIRMOVQ, IRMMOVQ, IMRMOVQ };

# Does fetched instruction require a constant word?
bool need_valC =
	icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };

################ Decode Stage    ###################################

## What register should be used as the A source?
word srcA = [
	icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ  } : rA;
	icode in { IPOPQ, IRET } : RRSP;
	1 : RNONE; # Don't need register
];

## What register should be used as the B source?
word srcB = [
	icode in { IOPQ, IRMMOVQ, IMRMOVQ  } : rB;
	icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;
	1 : RNONE;  # Don't need register
];

## What register should be used as the E destination?
word dstE = [
	icode in { IRRMOVQ } && Cnd : rB;
	icode in { IIRMOVQ, IOPQ} : rB;
	icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;
	1 : RNONE;  # Don't write any register
];

## What register should be used as the M destination?
word dstM = [
	icode in { IMRMOVQ, IPOPQ } : rA;
	1 : RNONE;  # Don't write any register
];

################ Execute Stage   ###################################

## Select input A to ALU
word aluA = [
	icode in { IRRMOVQ, IOPQ } : valA;
	icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ } : valC;
	icode in { ICALL, IPUSHQ } : -8;
	icode in { IRET, IPOPQ } : 8;
	# Other instructions don't need ALU
];

## Select input B to ALU
word aluB = [
	icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, 
		      IPUSHQ, IRET, IPOPQ } : valB;
	icode in { IRRMOVQ, IIRMOVQ } : 0;
	# Other instructions don't need ALU
];

## Set the ALU function
word alufun = [
	icode == IOPQ : ifun;
	1 : ALUADD;
];

## Should the condition codes be updated?
bool set_cc = icode in { IOPQ };

################ Memory Stage    ###################################

## Set read control signal
bool mem_read = icode in { IMRMOVQ, IPOPQ, IRET };

## Set write control signal
bool mem_write = icode in { IRMMOVQ, IPUSHQ, ICALL };

## Select memory address
word mem_addr = [
	icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ } : valE;
	icode in { IPOPQ, IRET } : valA;
	# Other instructions don't need address
];

## Select memory input data
word mem_data = [
	# Value from register
	icode in { IRMMOVQ, IPUSHQ } : valA;
	# Return PC
	icode == ICALL : valP;
	# Default: Don't write anything
];

## Determine instruction status
word Stat = [
	imem_error || dmem_error : SADR;
	!instr_valid: SINS;
	icode == IHALT : SHLT;
	1 : SAOK;
];

################ Program Counter Update ############################

## What address should instruction be fetched at

word new_pc = [
	# Call.  Use instruction constant
	icode == ICALL : valC;
	# Taken branch.  Use instruction constant
	icode == IJXX && Cnd : valC;
	# Completion of RET instruction.  Use value from stack
	icode == IRET : valM;
	# Default: Use incremented PC
	1 : valP;
];
#/* $end new-seq-all-hcl */

4.53

这里给出pipe-stall.hcl文件的内容,应该是对应于文件pipe-nobypass.hcl

#/* $begin pipe-all-hcl */
####################################################################
#    HCL Description of Control for Pipelined Y86-64 Processor     #
#    Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2014     #
####################################################################

## Your task is to make the pipeline work without using any forwarding
## The normal bypassing logic in the file is disabled.
## You can only change the pipeline control logic at the end of this file.
## The trick is to make the pipeline stall whenever there is a data hazard.

####################################################################
#    C Include's.  Don't alter these                               #
####################################################################

quote '#include <stdio.h>'
quote '#include "isa.h"'
quote '#include "pipeline.h"'
quote '#include "stages.h"'
quote '#include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'int main(int argc, char *argv[]){return sim_main(argc,argv);}'

####################################################################
#    Declarations.  Do not change/remove/delete any of these       #
####################################################################

##### Symbolic representation of Y86-64 Instruction Codes #############
wordsig INOP 	'I_NOP'
wordsig IHALT	'I_HALT'
wordsig IRRMOVQ	'I_RRMOVQ'
wordsig IIRMOVQ	'I_IRMOVQ'
wordsig IRMMOVQ	'I_RMMOVQ'
wordsig IMRMOVQ	'I_MRMOVQ'
wordsig IOPQ	'I_ALU'
wordsig IJXX	'I_JMP'
wordsig ICALL	'I_CALL'
wordsig IRET	'I_RET'
wordsig IPUSHQ	'I_PUSHQ'
wordsig IPOPQ	'I_POPQ'

##### Symbolic represenations of Y86-64 function codes            #####
wordsig FNONE    'F_NONE'        # Default function code

##### Symbolic representation of Y86-64 Registers referenced      #####
wordsig RRSP     'REG_RSP'    	     # Stack Pointer
wordsig RNONE    'REG_NONE'   	     # Special value indicating "no register"

##### ALU Functions referenced explicitly ##########################
wordsig ALUADD	'A_ADD'		     # ALU should add its arguments

##### Possible instruction status values                       #####
wordsig SBUB	'STAT_BUB'	# Bubble in stage
wordsig SAOK	'STAT_AOK'	# Normal execution
wordsig SADR	'STAT_ADR'	# Invalid memory address
wordsig SINS	'STAT_INS'	# Invalid instruction
wordsig SHLT	'STAT_HLT'	# Halt instruction encountered

##### Signals that can be referenced by control logic ##############

##### Pipeline Register F ##########################################

wordsig F_predPC 'pc_curr->pc'	     # Predicted value of PC

##### Intermediate Values in Fetch Stage ###########################

wordsig imem_icode  'imem_icode'      # icode field from instruction memory
wordsig imem_ifun   'imem_ifun'       # ifun  field from instruction memory
wordsig f_icode	'if_id_next->icode'  # (Possibly modified) instruction code
wordsig f_ifun	'if_id_next->ifun'   # Fetched instruction function
wordsig f_valC	'if_id_next->valc'   # Constant data of fetched instruction
wordsig f_valP	'if_id_next->valp'   # Address of following instruction
boolsig imem_error 'imem_error'	     # Error signal from instruction memory
boolsig instr_valid 'instr_valid'    # Is fetched instruction valid?

##### Pipeline Register D ##########################################
wordsig D_icode 'if_id_curr->icode'   # Instruction code
wordsig D_rA 'if_id_curr->ra'	     # rA field from instruction
wordsig D_rB 'if_id_curr->rb'	     # rB field from instruction
wordsig D_valP 'if_id_curr->valp'     # Incremented PC

##### Intermediate Values in Decode Stage  #########################

wordsig d_srcA	 'id_ex_next->srca'  # srcA from decoded instruction
wordsig d_srcB	 'id_ex_next->srcb'  # srcB from decoded instruction
wordsig d_rvalA 'd_regvala'	     # valA read from register file
wordsig d_rvalB 'd_regvalb'	     # valB read from register file

##### Pipeline Register E ##########################################
wordsig E_icode 'id_ex_curr->icode'   # Instruction code
wordsig E_ifun  'id_ex_curr->ifun'    # Instruction function
wordsig E_valC  'id_ex_curr->valc'    # Constant data
wordsig E_srcA  'id_ex_curr->srca'    # Source A register ID
wordsig E_valA  'id_ex_curr->vala'    # Source A value
wordsig E_srcB  'id_ex_curr->srcb'    # Source B register ID
wordsig E_valB  'id_ex_curr->valb'    # Source B value
wordsig E_dstE 'id_ex_curr->deste'    # Destination E register ID
wordsig E_dstM 'id_ex_curr->destm'    # Destination M register ID

##### Intermediate Values in Execute Stage #########################
wordsig e_valE 'ex_mem_next->vale'	# valE generated by ALU
boolsig e_Cnd 'ex_mem_next->takebranch' # Does condition hold?
wordsig e_dstE 'ex_mem_next->deste'      # dstE (possibly modified to be RNONE)

##### Pipeline Register M                  #########################
wordsig M_stat 'ex_mem_curr->status'     # Instruction status
wordsig M_icode 'ex_mem_curr->icode'	# Instruction code
wordsig M_ifun  'ex_mem_curr->ifun'	# Instruction function
wordsig M_valA  'ex_mem_curr->vala'      # Source A value
wordsig M_dstE 'ex_mem_curr->deste'	# Destination E register ID
wordsig M_valE  'ex_mem_curr->vale'      # ALU E value
wordsig M_dstM 'ex_mem_curr->destm'	# Destination M register ID
boolsig M_Cnd 'ex_mem_curr->takebranch'	# Condition flag
boolsig dmem_error 'dmem_error'	        # Error signal from instruction memory

##### Intermediate Values in Memory Stage ##########################
wordsig m_valM 'mem_wb_next->valm'	# valM generated by memory
wordsig m_stat 'mem_wb_next->status'	# stat (possibly modified to be SADR)

##### Pipeline Register W ##########################################
wordsig W_stat 'mem_wb_curr->status'     # Instruction status
wordsig W_icode 'mem_wb_curr->icode'	# Instruction code
wordsig W_dstE 'mem_wb_curr->deste'	# Destination E register ID
wordsig W_valE  'mem_wb_curr->vale'      # ALU E value
wordsig W_dstM 'mem_wb_curr->destm'	# Destination M register ID
wordsig W_valM  'mem_wb_curr->valm'	# Memory M value

####################################################################
#    Control Signal Definitions.                                   #
####################################################################

################ Fetch Stage     ###################################

## What address should instruction be fetched at
word f_pc = [
	# Mispredicted branch.  Fetch at incremented PC
	M_icode == IJXX && !M_Cnd : M_valA;
	# Completion of RET instruction
	W_icode == IRET : W_valM;
	# Default: Use predicted value of PC
	1 : F_predPC;
];

## Determine icode of fetched instruction
word f_icode = [
	imem_error : INOP;
	1: imem_icode;
];

# Determine ifun
word f_ifun = [
	imem_error : FNONE;
	1: imem_ifun;
];

# Is instruction valid?
bool instr_valid = f_icode in 
	{ INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,
	  IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ };

# Determine status code for fetched instruction
word f_stat = [
	imem_error: SADR;
	!instr_valid : SINS;
	f_icode == IHALT : SHLT;
	1 : SAOK;
];

# Does fetched instruction require a regid byte?
bool need_regids =
	f_icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, 
		     IIRMOVQ, IRMMOVQ, IMRMOVQ };

# Does fetched instruction require a constant word?
bool need_valC =
	f_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };

# Predict next value of PC
word f_predPC = [
	f_icode in { IJXX, ICALL } : f_valC;
	1 : f_valP;
];

################ Decode Stage ######################################


## What register should be used as the A source?
word d_srcA = [
	D_icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ  } : D_rA;
	D_icode in { IPOPQ, IRET } : RRSP;
	1 : RNONE; # Don't need register
];

## What register should be used as the B source?
word d_srcB = [
	D_icode in { IOPQ, IRMMOVQ, IMRMOVQ  } : D_rB;
	D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;
	1 : RNONE;  # Don't need register
];

## What register should be used as the E destination?
word d_dstE = [
	D_icode in { IRRMOVQ, IIRMOVQ, IOPQ} : D_rB;
	D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;
	1 : RNONE;  # Don't write any register
];

## What register should be used as the M destination?
word d_dstM = [
	D_icode in { IMRMOVQ, IPOPQ } : D_rA;
	1 : RNONE;  # Don't write any register
];

## What should be the A value?
##  DO NOT MODIFY THE FOLLOWING CODE.
## No forwarding.  valA is either valP or value from register file
word d_valA = [
	D_icode in { ICALL, IJXX } : D_valP; # Use incremented PC
	1 : d_rvalA;  # Use value read from register file
];

## No forwarding.  valB is value from register file
word d_valB = d_rvalB;

################ Execute Stage #####################################

## Select input A to ALU
word aluA = [
	E_icode in { IRRMOVQ, IOPQ } : E_valA;
	E_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ } : E_valC;
	E_icode in { ICALL, IPUSHQ } : -8;
	E_icode in { IRET, IPOPQ } : 8;
	# Other instructions don't need ALU
];

## Select input B to ALU
word aluB = [
	E_icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, 
		     IPUSHQ, IRET, IPOPQ } : E_valB;
	E_icode in { IRRMOVQ, IIRMOVQ } : 0;
	# Other instructions don't need ALU
];

## Set the ALU function
word alufun = [
	E_icode == IOPQ : E_ifun;
	1 : ALUADD;
];

## Should the condition codes be updated?
bool set_cc = E_icode == IOPQ &&
	# State changes only during normal operation
	!m_stat in { SADR, SINS, SHLT } && !W_stat in { SADR, SINS, SHLT };

## Generate valA in execute stage
word e_valA = E_valA;    # Pass valA through stage

## Set dstE to RNONE in event of not-taken conditional move
word e_dstE = [
	E_icode == IRRMOVQ && !e_Cnd : RNONE;
	1 : E_dstE;
];

################ Memory Stage ######################################

## Select memory address
word mem_addr = [
	M_icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ } : M_valE;
	M_icode in { IPOPQ, IRET } : M_valA;
	# Other instructions don't need address
];

## Set read control signal
bool mem_read = M_icode in { IMRMOVQ, IPOPQ, IRET };

## Set write control signal
bool mem_write = M_icode in { IRMMOVQ, IPUSHQ, ICALL };

#/* $begin pipe-m_stat-hcl */
## Update the status
word m_stat = [
	dmem_error : SADR;
	1 : M_stat;
];
#/* $end pipe-m_stat-hcl */

## Set E port register ID
word w_dstE = W_dstE;

## Set E port value
word w_valE = W_valE;

## Set M port register ID
word w_dstM = W_dstM;

## Set M port value
word w_valM = W_valM;

## Update processor status
word Stat = [
	W_stat == SBUB : SAOK;
	1 : W_stat;
];

################ Pipeline Register Control #########################

# Should I stall or inject a bubble into Pipeline Register F?
# At most one of these can be true.
bool F_bubble = 0;
bool F_stall =
	# Modify the following to stall the update of pipeline register F
	0 ||
	# Stalling at fetch while ret passes through pipeline
	IRET in { D_icode, E_icode, M_icode };

# Should I stall or inject a bubble into Pipeline Register D?
# At most one of these can be true.
bool D_stall = 
	# Modify the following to stall the instruction in decode
	0;

bool D_bubble =
	# Mispredicted branch
	(E_icode == IJXX && !e_Cnd) ||
	# Stalling at fetch while ret passes through pipeline
	!(E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB }) &&
	# but not condition for a generate/use hazard
	!0 &&
	  IRET in { D_icode, E_icode, M_icode };

# Should I stall or inject a bubble into Pipeline Register E?
# At most one of these can be true.
bool E_stall = 0;
bool E_bubble =
	# Mispredicted branch
	(E_icode == IJXX && !e_Cnd) ||
	# Modify the following to inject bubble into the execute stage
	0;

# Should I stall or inject a bubble into Pipeline Register M?
# At most one of these can be true.
bool M_stall = 0;
# Start injecting bubbles as soon as exception passes through memory stage
bool M_bubble = m_stat in { SADR, SINS, SHLT } || W_stat in { SADR, SINS, SHLT };

# Should I stall or inject a bubble into Pipeline Register W?
bool W_stall = W_stat in { SADR, SINS, SHLT };
bool W_bubble = 0;
#/* $end pipe-all-hcl */
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值