diff --git a/osaca/data/csx.yml b/osaca/data/csx.yml index 9f20b51..42b48aa 100644 --- a/osaca/data/csx.yml +++ b/osaca/data/csx.yml @@ -417,7 +417,19 @@ instruction_forms: scale: 1 - class: register name: xmm - throughput: 1.0 + throughput: 0.5 + latency: 4.0 # 1*p23+1*p2D3D + port_pressure: [[1, '23'], [1, [2D, 3D]]] +- name: vmovapd + operands: + - class: memory + base: gpr + offset: ~ + index: gpr + scale: 1 + - class: register + name: ymm + throughput: 0.5 latency: 4.0 # 1*p23+1*p2D3D port_pressure: [[1, '23'], [1, [2D, 3D]]] - name: vmovapd @@ -429,7 +441,7 @@ instruction_forms: scale: 1 - class: register name: ymm - throughput: 1.0 + throughput: 0.5 latency: 4.0 # 1*p23+1*p2D3D port_pressure: [[1, '23'], [1, [2D, 3D]]] - name: vmovapd @@ -441,7 +453,7 @@ instruction_forms: offset: ~ index: gpr scale: 1 - throughput: 1.0 + throughput: 0.5 latency: 4.0 # 1*p23+1*p4 port_pressure: [[1, '23'], [1, '4']] - name: vmovapd diff --git a/osaca/data/snb.yml b/osaca/data/snb.yml index 69b25bb..2543b69 100644 --- a/osaca/data/snb.yml +++ b/osaca/data/snb.yml @@ -2632,6 +2632,13 @@ instruction_forms: port_pressure: [[10, '0'], [4, '01'], [3, '015'], [1, '05'], [11, '1'], [1, '15'], [2, '23'], [1, '4'], [25, '5']] throughput: 27.0 uops: 58 +- name: JA + operands: + - class: identifier + latency: 0 + port_pressure: [] + throughput: 0.0 + uops: 1 - name: JNE operands: - class: identifier @@ -4196,6 +4203,16 @@ instruction_forms: port_pressure: [[1, '015']] throughput: 0.3333333333333333 uops: 1 +- name: ADD + operands: + - class: register + name: gpr + - class: register + name: gpr + latency: 1 + port_pressure: [[1, '015']] + throughput: 0.3333333333333333 + uops: 1 - name: REX ADD operands: - class: immediate diff --git a/osaca/semantics/arch_semantics.py b/osaca/semantics/arch_semantics.py index eb6802b..b28e8dc 100755 --- a/osaca/semantics/arch_semantics.py +++ b/osaca/semantics/arch_semantics.py @@ -135,39 +135,9 @@ class ArchSemantics(ISASemantics): ) if instruction_data: # instruction form in DB - throughput = instruction_data['throughput'] - port_pressure = self._machine_model.average_port_pressure( - instruction_data['port_pressure'] + latency_wo_load = self._handle_instruction_found( + instruction_data, port_number, instruction_form, flags ) - instruction_form['port_uops'] = instruction_data['port_pressure'] - try: - assert isinstance(port_pressure, list) - assert len(port_pressure) == port_number - instruction_form['port_pressure'] = port_pressure - if sum(port_pressure) == 0 and throughput is not None: - # port pressure on all ports 0 --> not bound to a port - flags.append(INSTR_FLAGS.NOT_BOUND) - except AssertionError: - warnings.warn( - 'Port pressure could not be imported correctly from database. ' - + 'Please check entry for:\n {}'.format(instruction_form) - ) - instruction_form['port_pressure'] = [0.0 for i in range(port_number)] - instruction_form['port_uops'] = [] - flags.append(INSTR_FLAGS.TP_UNKWN) - if throughput is None: - # assume 0 cy and mark as unknown - throughput = 0.0 - flags.append(INSTR_FLAGS.TP_UNKWN) - latency = instruction_data['latency'] - latency_wo_load = latency - if latency is None: - # assume 0 cy and mark as unknown - latency = 0.0 - latency_wo_load = latency - flags.append(INSTR_FLAGS.LT_UNKWN) - if INSTR_FLAGS.HAS_LD in instruction_form['flags']: - flags.append(INSTR_FLAGS.LD) else: # instruction could not be found in DB assign_unknown = True @@ -217,9 +187,9 @@ class ArchSemantics(ISASemantics): ), ) ] - instruction_form['port_uops'] = list(chain( - instruction_data_reg['port_pressure'], load_port_uops - )) + instruction_form['port_uops'] = list( + chain(instruction_data_reg['port_pressure'], load_port_uops) + ) if assign_unknown: # --> mark as unknown and assume 0 cy for latency/throughput @@ -242,12 +212,51 @@ class ArchSemantics(ISASemantics): instruction_form['latency_cp'] = 0 instruction_form['latency_lcd'] = 0 - def substitute_mem_address(self, operands): - reg_ops = [op for op in operands if 'register' in op] - reg_type = self._parser.get_reg_type(reg_ops[0]['register']) - return [self.convert_mem_to_reg(op, reg_type) for op in operands] + def _handle_instruction_found(self, instruction_data, port_number, instruction_form, flags): + throughput = instruction_data['throughput'] + port_pressure = self._machine_model.average_port_pressure( + instruction_data['port_pressure'] + ) + instruction_form['port_uops'] = instruction_data['port_pressure'] + try: + assert isinstance(port_pressure, list) + assert len(port_pressure) == port_number + instruction_form['port_pressure'] = port_pressure + if sum(port_pressure) == 0 and throughput is not None: + # port pressure on all ports 0 --> not bound to a port + flags.append(INSTR_FLAGS.NOT_BOUND) + except AssertionError: + warnings.warn( + 'Port pressure could not be imported correctly from database. ' + + 'Please check entry for:\n {}'.format(instruction_form) + ) + instruction_form['port_pressure'] = [0.0 for i in range(port_number)] + instruction_form['port_uops'] = [] + flags.append(INSTR_FLAGS.TP_UNKWN) + if throughput is None: + # assume 0 cy and mark as unknown + throughput = 0.0 + flags.append(INSTR_FLAGS.TP_UNKWN) + latency = instruction_data['latency'] + latency_wo_load = latency + if latency is None: + # assume 0 cy and mark as unknown + latency = 0.0 + latency_wo_load = latency + flags.append(INSTR_FLAGS.LT_UNKWN) + if INSTR_FLAGS.HAS_LD in instruction_form['flags']: + flags.append(INSTR_FLAGS.LD) + return latency_wo_load - def convert_mem_to_reg(self, memory, reg_type, reg_id='0'): + def substitute_mem_address(self, operands): + # reg_ops = [op for op in operands if 'register' in op] + # reg_type = self._parser.get_reg_type(reg_ops[0]['register']) + return [self._create_reg_wildcard() if 'memory' in op else op for op in operands] + + def _create_reg_wildcard(self): + return {'*': '*'} + + def convert_op_to_reg(self, reg_type, reg_id='0'): if self._isa == 'x86': if reg_type == 'gpr': register = {'register': {'name': 'r' + str(int(reg_id) + 9)}} diff --git a/osaca/semantics/hw_model.py b/osaca/semantics/hw_model.py index 45e4036..26a9608 100755 --- a/osaca/semantics/hw_model.py +++ b/osaca/semantics/hw_model.py @@ -347,11 +347,21 @@ class MachineModel(object): else: return False - def _check_operands(self, i_operands, operands): + def _check_operands(self, i_operand, operand): + # check for wildcard + if '*' in operand: + if ( + 'class' in i_operand + and i_operand['class'] == 'register' + or 'register' in i_operand + ): + return True + else: + return False if self._data['isa'].lower() == 'aarch64': - return self._check_AArch64_operands(i_operands, operands) + return self._check_AArch64_operands(i_operand, operand) if self._data['isa'].lower() == 'x86': - return self._check_x86_operands(i_operands, operands) + return self._check_x86_operands(i_operand, operand) def _check_AArch64_operands(self, i_operand, operand): if 'class' in operand: