1def get_argument_string(function_shortcut): 

2 args = function_shortcut[function_shortcut.index('[') + 1: -1] 

3 arg_string = "(" 

4 for arg in args.split(","): 

5 arg = arg.strip() 

6 if not arg: 6 ↛ 7line 6 didn't jump to line 7, because the condition on line 6 was never true

7 continue 

8 if arg in ('0', '1', '2', '3', '4', '5'): 

9 arg_string += "{" + arg + "}," 

10 else: 

11 arg_string += arg + "," 

12 arg_string = arg_string[:-1] + ")" 

13 return arg_string 

14 

15 

16def get_vector_instruction_set_ppc(data_type='double', instruction_set='vsx'): 

17 if instruction_set != 'vsx': 

18 raise NotImplementedError(instruction_set) 

19 

20 base_names = { 

21 '+': 'add[0, 1]', 

22 '-': 'sub[0, 1]', 

23 '*': 'mul[0, 1]', 

24 '/': 'div[0, 1]', 

25 'sqrt': 'sqrt[0]', 

26 'rsqrt': 'rsqrte[0]', # rsqrt is available too, but not on Clang 

27 

28 'loadU': 'xl[0x0, 0]', 

29 'loadA': 'ld[0x0, 0]', 

30 'storeU': 'xst[1, 0x0, 0]', 

31 'storeA': 'st[1, 0x0, 0]', 

32 'storeAAndFlushCacheline': 'stl[1, 0x0, 0]', 

33 

34 'abs': 'abs[0]', 

35 '==': 'cmpeq[0, 1]', 

36 '!=': 'cmpne[0, 1]', 

37 '<=': 'cmple[0, 1]', 

38 '<': 'cmplt[0, 1]', 

39 '>=': 'cmpge[0, 1]', 

40 '>': 'cmpgt[0, 1]', 

41 '&': 'and[0, 1]', 

42 '|': 'or[0, 1]', 

43 'blendv': 'sel[0, 1, 2]', 

44 

45 ('any', '=='): 'any_eq[0, 1]', 

46 ('any', '!='): 'any_ne[0, 1]', 

47 ('any', '<='): 'any_le[0, 1]', 

48 ('any', '<'): 'any_lt[0, 1]', 

49 ('any', '>='): 'any_ge[0, 1]', 

50 ('any', '>'): 'any_gt[0, 1]', 

51 ('all', '=='): 'all_eq[0, 1]', 

52 ('all', '!='): 'all_ne[0, 1]', 

53 ('all', '<='): 'all_le[0, 1]', 

54 ('all', '<'): 'all_lt[0, 1]', 

55 ('all', '>='): 'all_ge[0, 1]', 

56 ('all', '>'): 'all_gt[0, 1]', 

57 } 

58 

59 bits = {'double': 64, 

60 'float': 32, 

61 'int': 32} 

62 

63 width = 128 // bits[data_type] 

64 intwidth = 128 // bits['int'] 

65 

66 result = dict() 

67 result['bytes'] = 16 

68 

69 for intrinsic_id, function_shortcut in base_names.items(): 

70 function_shortcut = function_shortcut.strip() 

71 name = function_shortcut[:function_shortcut.index('[')] 

72 

73 arg_string = get_argument_string(function_shortcut) 

74 

75 result[intrinsic_id] = 'vec_' + name + arg_string 

76 

77 if data_type == 'double': 

78 # Clang and XL C++ are missing these for doubles 

79 result['loadA'] = '(__vector double)' + result['loadA'].format('(float*) {0}') 

80 result['storeA'] = result['storeA'].format('(float*) {0}', '(__vector float) {1}') 

81 result['storeAAndFlushCacheline'] = result['storeAAndFlushCacheline'].format('(float*) {0}', 

82 '(__vector float) {1}') 

83 

84 result['+int'] = "vec_add({0}, {1})" 

85 

86 result['width'] = width 

87 result['intwidth'] = intwidth 

88 result[data_type] = f'__vector {data_type}' 

89 result['int'] = '__vector int' 

90 result['bool'] = f'__vector __bool {"long long" if data_type == "double" else "int"}' 

91 result['headers'] = ['<altivec.h>', '"ppc_altivec_helpers.h"'] 

92 

93 result['makeVecConst'] = '((' + result[data_type] + '){{' + \ 

94 ", ".join(['(' + data_type + ') {0}' for _ in range(width)]) + '}})' 

95 result['makeVec'] = '((' + result[data_type] + '){{' + \ 

96 ", ".join(['{' + data_type + '} {' + str(i) + '}' for i in range(width)]) + '}})' 

97 result['makeVecConstInt'] = '((' + result['int'] + '){{' + ", ".join(['(int) {0}' for _ in range(intwidth)]) + '}})' 

98 result['makeVecInt'] = '((' + result['int'] + '){{(int) {0}, (int) {1}, (int) {2}, (int) {3}}})' 

99 

100 result['any'] = 'vec_any_ne({0}, ((' + result['bool'] + ') {{' + ", ".join(['0'] * width) + '}}))' 

101 result['all'] = 'vec_all_ne({0}, ((' + result['bool'] + ') {{' + ", ".join(['0'] * width) + '}}))' 

102 

103 result['cachelineSize'] = 'cachelineSize()' 

104 result['cachelineZero'] = 'cachelineZero((void*) {0})' 

105 

106 return result