Mercurial > pub > dyncall > dyncall
comparison dyncallback/dyncall_args_x64.c @ 544:111236b31c75
- C++ non-trivial aggregate-by-value handling:
* dyncallback support for dcbArgAggr()
* better doc
author | Tassilo Philipp |
---|---|
date | Tue, 31 May 2022 18:25:13 +0200 |
parents | 804df3409b51 |
children | 0455834d29a1 |
comparison
equal
deleted
inserted
replaced
543:781b308aa320 | 544:111236b31c75 |
---|---|
72 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLongLong(p); } | 72 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLongLong(p); } |
73 | 73 |
74 DCdouble dcbArgDouble (DCArgs* p) { return *arg_f64(p); } | 74 DCdouble dcbArgDouble (DCArgs* p) { return *arg_f64(p); } |
75 DCfloat dcbArgFloat (DCArgs* p) { return *(float*)arg_f64(p); } | 75 DCfloat dcbArgFloat (DCArgs* p) { return *(float*)arg_f64(p); } |
76 | 76 |
77 void dcbArgAggr (DCArgs* p, DCpointer target) | 77 DCpointer dcbArgAggr (DCArgs* p, DCpointer target) |
78 { | 78 { |
79 int i; | 79 int i; |
80 DCaggr *ag = *(p->aggrs++); | 80 DCaggr *ag = *(p->aggrs++); |
81 | 81 |
82 if(!ag) { | 82 if(!ag) { |
83 /* non-trivial aggr: retrieve as ptr, user is supposed to make copy */ | 83 /* non-trivial aggr: retrieve as ptr, user is supposed to make copy */ |
84 target = dcbArgPointer(p); | 84 return dcbArgPointer(p); |
85 return; | |
86 } | 85 } |
87 | 86 |
88 #if defined(DC_UNIX) | 87 #if defined(DC_UNIX) |
89 DCRegCount_x64 n_regs = { p->reg_count.i, p->reg_count.f }; | 88 DCRegCount_x64 n_regs = { p->reg_count.i, p->reg_count.f }; |
90 | 89 |
100 | 99 |
101 if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs)) | 100 if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs)) |
102 { | 101 { |
103 memcpy(target, p->stack_ptr, ag->size); | 102 memcpy(target, p->stack_ptr, ag->size); |
104 p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); // advance to next full stack slot | 103 p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); // advance to next full stack slot |
105 return; | 104 } |
105 else | |
106 { | |
107 for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i) | |
108 { | |
109 switch (ag->sysv_classes[i]) | |
110 { | |
111 case SYSVC_INTEGER: ((DClonglong*)target)[i] = dcbArgLongLong(p); break; | |
112 case SYSVC_SSE: ((DCdouble *)target)[i] = dcbArgDouble (p); break; | |
113 /* @@@AGGR implement when implementing x87 types */ | |
114 default: | |
115 assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier"); | |
116 } | |
117 } | |
106 } | 118 } |
107 | 119 |
108 | 120 return target; |
109 for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i) | |
110 { | |
111 switch (ag->sysv_classes[i]) | |
112 { | |
113 case SYSVC_INTEGER: ((DClonglong*)target)[i] = dcbArgLongLong(p); break; | |
114 case SYSVC_SSE: ((DCdouble *)target)[i] = dcbArgDouble (p); break; | |
115 /* @@@AGGR implement when implementing x87 types */ | |
116 default: | |
117 assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier"); | |
118 } | |
119 } | |
120 | 121 |
121 #else | 122 #else |
122 | 123 |
123 switch (ag->size) { | 124 switch (ag->size) { |
124 case 1: *(DCchar *)target = dcbArgChar (p); break; | 125 case 1: *(DCchar *)target = dcbArgChar (p); break; |
143 int i; | 144 int i; |
144 DCaggr *ag = *(args->aggrs++); | 145 DCaggr *ag = *(args->aggrs++); |
145 | 146 |
146 if(!ag) { | 147 if(!ag) { |
147 /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */ | 148 /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */ |
148 result->p = args->reg_data.i[0]; | 149 result->p = (DCpointer) args->reg_data.i[0]; |
149 return; | 150 return; |
150 } | 151 } |
151 | 152 |
152 if (args->aggr_return_register >= 0) { | 153 if (args->aggr_return_register >= 0) { |
153 DCpointer dest = (DCpointer) args->reg_data.i[args->aggr_return_register]; | 154 DCpointer dest = (DCpointer) args->reg_data.i[args->aggr_return_register]; |